Condividi tramite


Utilizzo dell'hint per la query USE PLAN

L'hint per la query USE PLAN accetta xml_plan come argomento. xml_plan è un valore letterale stringa derivato dal piano di query in formato XML creato per la query. È possibile specificare USE PLAN come hint per la query in un'istruzione SQL autonoma oppure nel parametro @hints di una guida di piano. Per associare un piano di query a una guida di piano, si consiglia di utilizzare il parametro xml_showplan in sp_create_plan_guide o la stored procedure sp_create_plan_guide_from_handle.

Nota importanteImportante

È consigliabile indicare sempre xml_plan come un valore letterale Unicode specificando il prefisso N, come in N'xml_plan'. Ciò garantisce che i caratteri del piano specifici dello standard Unicode non vengono persi quando Motore di database di SQL Server interpreta la stringa.

In SQL Server, è possibile creare piani di query in formato XML nei modi seguenti:

  • SET SHOWPLAN_XML

    Nota importanteImportante

    Se si generano piani di query utilizzando SET SHOWPLAN_XML, prima di utilizzare un piano con l'hint per la query USE PLAN, per le virgolette (') presenti nel piano è necessario utilizzare il carattere di escape rappresentato da una seconda virgoletta. Ad esempio, per un piano che contiene WHERE A.varchar = 'This is a string' è necessario utilizzare i caratteri di escape modificando il codice in WHERE A.varchar = ''This is a string''.

  • SET STATISTICS XML

  • Esecuzione di query sulla colonna query_plan della funzione a gestione dinamica sys.dm_exec_query_plan.

  • Classi di evento Showplan XML, Showplan XML Statistics Profile e Showplan XML For Query Compile di SQL Server Profiler.

Per ulteriori informazioni sulla generazione e sull'analisi dei piani di query, vedere Analisi di una query.

Il piano di query in formato XML specificato in xml_plan deve essere convalidato in base allo schema XSD Showplanxml.xsd disponibile nella directory di installazione di SQL Server. Nel percorso che include gli elementi <ShowPlanXML> <BatchSequence> <Batch> <Statements> deve inoltre essere presente uno degli elementi seguenti:

  • Uno o più elementi <StmtSimple>, uno dei quali contiene un sottoelemento <QueryPlan>.

  • Un elemento <StmtCursor> che contiene un solo sottoelemento <CursorPlan>.

  • Uno o più elementi <StmtSimple> senza un sottoelemento <QueryPlan> e un elemento <StmtCursor> che contiene un sottoelemento <CursorPlan>.

È possibile modificare il piano prima di utilizzarlo con USE PLAN, ad esempio cambiare l'ordine e gli operatori dei join e modificare le scansioni e le ricerche. Il formato del piano deve tuttavia corrispondere a Showplanxml.xsd e potrebbe non essere possibile forzare un piano che è stato modificato. Se in un hint USE PLAN si utilizza un piano diverso da quelli che SQL Server prende in considerazione per la query durante l'ottimizzazione, verrà generato un errore.

I piani query generati con l'hint per query USE PLAN vengono memorizzati nella cache come tutti gli altri piani query.

Limitazioni dell'hint per la query USE PLAN

Se si apportano modifiche al database, ad esempio si eliminano indici, è possibile che un piano di query specificato da USE PLAN non sia più valido. Un piano di query può non essere più valido anche se il riferimento a un oggetto eliminato non è diretto. Ad esempio, è possibile che un piano di query non faccia riferimento in modo esplicito a un indice univoco, ma tale indice applica comunque un vincolo di unicità ai dati. Un piano di query al quale fa riferimento USE PLAN può utilizzare tale vincolo per evitare di utilizzare operatori specifici per imporre l'unicità.

L'installazione di un Service Pack o di una nuova versione di SQL Server a volte può impedire l'applicazione di un piano generato da una versione precedente. È pertanto necessario testare tutti gli hint USE PLAN ogni volta che si aggiorna il server.

Se si utilizza l'hint USE PLAN in una query, tutti gli hint di join e di indice utilizzati nella stessa query verranno ignorati.

Non è possibile utilizzare USE PLAN con gli hint per query FORCE ORDER, EXPAND VIEWS, GROUP, UNION o JOIN o quando SET FORCEPLAN è impostata su ON.

Tramite USE PLAN è possibile forzare solo i piani di query che possono essere trovati in base alla normale strategia di ricerca di Query Optimizer. In questi piani in genere è specificato che un figlio di ogni join è al livello foglia. Se si utilizza USE PLAN per imporre altri tipi di query, verrà generato un errore.

Elementi del piano di query forzati

Con l'hint USE PLAN, non vengono forzati tutti gli elementi del piano di query in formato XML. Gli elementi che calcolano le espressioni scalari vengono ignorati, come anche alcune espressioni relazionali. Vengono forzati i tipi di elementi seguenti del piano di query:

  • La struttura ad albero e l'ordine di valutazione del piano.

  • Gli algoritmi di esecuzione, ad esempio i tipi di join, l'ordinamento e le unioni.

  • Le operazioni sugli indici, ad esempio le scansioni, le ricerche, le intersezioni e le unioni.

  • Gli oggetti a cui viene fatto riferimento in modo esplicito, ad esempio tabelle, indici e funzioni.

In particolare, SQL Server forza gli elementi LogicalOp, PhysicalOp e NodeID trovati nell'elemento <RelOp> e inoltre qualsiasi sottoelemento correlato all'operatore <PhysicalOp>. Qualsiasi altro contenuto nell'elemento <RelOp> non viene considerato da USE PLAN.

Nota importanteImportante

Le informazioni relative alle stime della cardinalità previste dall'elemento <EstimateRows> non vengono forzate dall'hint per le query USE PLAN. Query Optimizer utilizza la stima della cardinalità per determinare la quantità di memoria da destinare all'esecuzione di una query e pertanto è consigliabile mantenere statistiche precise, anche quando si utilizza USE PLAN. Per ulteriori informazioni, vedere Utilizzo di statistiche per migliorare le prestazioni di esecuzione delle query.

Nella tabella seguente sono elencati i valori degli operatori relazionali imposti tramite l'hint per le query USE PLAN per entrambi gli elementi PhysicalOp e LogicalOp e gli eventuali sottoelementi necessari per ogni valore PhysicalOp. Vengono inoltre riportate le informazioni aggiuntive necessarie per ogni operatore nel formato di percorsi di tipo XPath relativi al sottoelemento.

PhysicalOp

LogicalOp

Sottoelemento

Informazioni aggiuntive1

Concatenation

Concatenation

Async Concat

Concat

Non applicabile

Constant Scan

Constant Scan

ConstantScan

Non applicabile

Deleted Scan

Deleted Scan

DeletedScan

Object/@Table

UDX

UDX

Extension

@UDXName

Hash Match

Inner Join

Left Outer Join

Right Outer Join

Full Outer Join

Left Semi Join

Left Anti Semi Join

Right Semi Join

Right Anti Semi Join

Aggregate

Partial Aggregate

Flow Distinct

Union

Hash

Non applicabile

RID Lookup

RID Lookup

IndexScan

Object/@Database, Object/@Schema, Object/@Table

Index Scan

Clustered Index Scan

Index Scan

Clustered Index Scan

IndexScan

Object/@Database, Object/@Schema, Object/@Table Object/@Index

Index Seek

Clustered Index Seek

Index Seek

Clustered Index Seek

IndexScan

Object/@Database, Object/@Schema, Object/@Table Object/@Index

Inserted Scan

Inserted Scan

InsertedScan

Object/@Table

Log Row Scan

Log Row Scan

LogRowScan

Non applicabile

Merge Join

Inner Join

Left Outer Join

Right Outer Join

Full Outer Join

Left Semi Join

Left Anti Semi Join

Right Semi Join

Right Anti Semi Join

Cross Join

Concatenation

Union

Merge

Non applicabile

Merge Interval

Merge Interval

MergeInterval

Non applicabile

Nested Loops

Inner Join

Left Outer Join

Right Outer Join

Full Outer Join

Left Semi Join

Left Anti Semi Join

Right Semi Join

Right Anti Semi Join

Cross Join

NestedLoops

Non applicabile

Parallelism

Gather Streams

Repartition Streams

Distribute Streams

Parallelism

Non applicabile

Row Count Spool

Eager Spool

Lazy Spool

RowCountSpool2

Non applicabile

Segment

Segment

Segment

Non applicabile

Sequence

Sequence

Sequence

Non applicabile

Sequence Project

Compute Scalar

SequenceProject

Non applicabile

Sort

Sort

Distinct Sort

Sort

Non applicabile

Table Spool

Index Spool

Eager Spool

Lazy Spool

Spool2

@PrimaryNodeId (solo per spool secondari)

../RelOp/@NodeId (solo per RelOps che rappresentano spool primari)

Stream Aggregate

Aggregate

StreamAggregate

Non applicabile

Switch

Switch

Switch

Non applicabile

Table Scan

Table Scan

TableScan

Object/@Database, Object/@Schema, Object/@Table

Table-valued function

Table-valued function

TableValuedFunction

Object/@Database, Object/@Schema, Object/@Table

(il nome della funzione con valori di tabella è Object/@Table)

Top

Top

Top

Non applicabile

Sort

Sort

Sort

Non applicabile

Top Sort

TopN Sort

TopSort

Non applicabile

Table Insert

Insert

Update

Object/@Table

1 Per forzare l'utilizzo di un piano con USE PLAN, il numero e l'ordine di questi valori di input per ogni operatore relazionale deve corrispondere a quello visualizzato nella tabella.

2 L'imposizione di un utilizzo forzato di un piano è limitata dal fatto che se il piano contiene un sottoelemento <RowCountSpool>, è possibile che in un piano forzato venga visualizzato come un sottoelemento <RowCountSpool> o <Spool>. Allo stesso modo, se il piano contiene un sottoelemento <Spool>, è possibile che in un piano forzato venga visualizzato come un sottoelemento <Spool> o <RowCountSpool>.

Gli operatori Assert, Bitmap, ComputeScalar e PrintDataFlow vengono ignorati da USE PLAN. L'operatore Filter viene considerato da USE PLAN, ma non è possibile forzarne la posizione esatta nel piano.

Per ulteriori informazioni sugli operatori logici e fisici utilizzati nei piani di query, vedere Guida di riferimento agli operatori logici e fisici.

Supporto dei cursori

È possibile utilizzare l'hint per le query USE PLAN insieme a query che specificano cursori statici o fast forward-only, se richiesto tramite Transact-SQL o una funzione per i cursori API. Sono supportati i cursori statici Transact-SQL con un'opzione forward-only. I cursori dinamici, gestiti da keyset e forward-only non sono supportati.

Per ulteriori informazioni, vedere Utilizzo dell'hint USE PLAN nelle query con cursori.