Hint per la query (Transact-SQL)
Gli hint per la query specificano che gli hint indicati devono essere utilizzati in tutta la query. Gli hint per la query influiscono su tutti gli operatori dell'istruzione. Se la query principale include l'operatore UNION, la clausola OPTION può essere specificata solo nell'ultima query che prevede un'operazione di tipo UNION. Gli hint per la query vengono specificati come parte della clausola OPTION. Se in seguito alla presenza di uno o più hint per la query non viene creato un piano valido da Query Optimizer, viene generato l'errore 8622.
Attenzione |
---|
Poiché Query Optimizer di SQL Server in genere seleziona il piano di esecuzione migliore per una query, è consigliabile utilizzare hint solo se strettamente necessario e sempre da parte di sviluppatori e amministratori esperti di database. |
Si applica a:
Sintassi
<query_hint > ::=
{ { HASH | ORDER } GROUP
| { CONCAT | HASH | MERGE } UNION
| { LOOP | MERGE | HASH } JOIN
| FAST number_rows
| FORCE ORDER
| MAXDOP number_of_processors
| OPTIMIZE FOR ( @variable_name { UNKNOWN | = literal_constant } [ , ...n ] )
| OPTIMIZE FOR UNKNOWN
| PARAMETERIZATION { SIMPLE | FORCED }
| RECOMPILE
| ROBUST PLAN
| KEEP PLAN
| KEEPFIXED PLAN
| EXPAND VIEWS
| MAXRECURSION number
| USE PLAN N'xml_plan'| TABLE HINT ( exposed_object_name [ , <table_hint> [ [, ]...n ] ] )<table_hint> ::=
[ NOEXPAND ] {
INDEX (index_value [ ,...n ] ) | INDEX = (index_value)
| FASTFIRSTROW
| FORCESEEK
| HOLDLOCK
| NOLOCK
| NOWAIT
| PAGLOCK
| READCOMMITTED
| READCOMMITTEDLOCK
| READPAST
| READUNCOMMITTED
| REPEATABLEREAD
| ROWLOCK
| SERIALIZABLE
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
Argomenti
{ HASH | ORDER } GROUP
Specifica che nelle funzioni di aggregazione elencate nella clausola GROUP BY, DISTINCT o COMPUTE della query devono essere utilizzate operazioni di hashing o di ordinamento.{ MERGE | HASH | CONCAT } UNION
Specifica che per tutte le operazioni UNION vengono eseguite operazioni di unione, hashing o concatenazione dei set UNION. Se viene specificato più di un hint UNION, Query Optimizer seleziona la strategia meno onerosa tra gli hint specificati.{ LOOP | MERGE | HASH } JOIN
Specifica che tutte le operazioni JOIN vengono eseguite da LOOP JOIN, MERGE JOIN o HASH JOIN nell'intera query. Se vengono specificati più hint di join, Query Optimizer seleziona la strategia di join meno onerosa tra i join consentiti.Se nella stessa query un hint di join viene specificato nella clausola FROM anche per una particolare coppia di tabelle, tale hint risulta prioritario rispetto all'unione in join delle due tabelle. Gli hint per la query devono essere comunque rispettati. L'hint di join della coppia di tabelle pertanto consente di limitare solo la selezione dei metodi di join consentiti nell'hint per la query. Per ulteriori informazioni, vedere Hint di join (Transact-SQL).
FAST number_rows
Specifica che la query è ottimizzata per il recupero rapido delle prime righe specificate in number_rows. Si tratta di un numero intero non negativo. Dopo la restituzione del numero di righe definito da number_rows, l'esecuzione della query continua e viene generato il set di risultati completo.FORCE ORDER
Specifica che l'ordine di join indicato dalla sintassi della query viene conservato durante l'ottimizzazione della query. L'utilizzo dell'hint FORCE ORDER non ha alcun effetto sulla possibile inversione dei ruoli in Query Optimizer. Per ulteriori informazioni, vedere Informazioni sugli hash join.[!NOTA]
In un'istruzione MERGE, l'accesso alla tabella di origine viene eseguito prima della tabella di destinazione come ordine di join predefinito, a meno che non sia specificata la clausola WHEN SOURCE NOT MATCHED. Specificando FORCE ORDER viene conservato questo comportamento predefinito.
Per informazioni su come Query Optimizer di SQL Server consente di applicare l'hint FORCE ORDER quando in una query è inclusa una vista, vedere Risoluzione delle viste.
MAXDOP number
Viene eseguito l'override dell'opzione di configurazione max degree of parallelism di sp_configure e di Resource Governor per la query che consente di specificare tale opzione. L'hint per la query MAXDOP può superare il valore configurato con sp_configure. Se MAXDOP supera il valore configurato con Resource Governor, nel Motore di database viene utilizzato il valore MAXDOP di Resource Governor, descritto in ALTER WORKLOAD GROUP (Transact-SQL). Quando si utilizza l'hint per la query MAXDOP sono valide tutte le regole semantiche utilizzate con l'opzione di configurazione max degree of parallelism. Per ulteriori informazioni, vedere Opzione max degree of parallelism.Attenzione L'impostazione di MAXDOP su zero consente al server di scegliere il massimo grado di parallelismo, ovvero internamente il valore DOP di 64.
OPTIMIZE FOR ( @variable\_name { UNKNOWN | = literal_constant } [ , ...n ] )
Consente a Query Optimizer di utilizzare un valore specifico per una variabile locale quando la query viene compilata e ottimizzata. Il valore viene utilizzato durante l'ottimizzazione della query e non durante la sua esecuzione.@variable\_name
Nome di una variabile locale utilizzata in una query alla quale è possibile assegnare un valore da utilizzare con l'hint per la query OPTIMIZE FOR.UNKNOWN
Specifica che Query Optimizer utilizza dati statistici anziché il valore iniziale per determinare il valore per una variabile locale durante l'ottimizzazione della query.literal_constant
Valore letterale costante da assegnare a @variable\_name per l'utilizzo con l'hint per la query OPTIMIZE FOR. literal_constant viene utilizzato solo durante l'ottimizzazione della query e non come valore di @variable\_name durante l'esecuzione della query. literal_constant può essere di un tipo di dati di sistema qualsiasi di SQL Server che sia possibile esprimere come costante letterale. Il tipo di dati di literal_constant deve supportare la conversione implicita nel tipo di dati a cui @variable\_name fa riferimento nella query.
OPTIMIZE FOR può annullare la funzionalità di rilevamento predefinita dei parametri di Query Optimizer oppure può essere utilizzato durante la creazione delle guide di piano. Per ulteriori informazioni, vedere Ricompilazione di stored procedure e Ottimizzazione delle query nelle applicazioni distribuite tramite le guide di piano.
OPTIMIZE FOR UNKNOWN
Indica a Query Optimizer di utilizzare dati statistici anziché i valori iniziali per tutte le variabili locali quando la query viene compilata e ottimizzata, includendo parametri creati con parametrizzazione forzata. Per ulteriori informazioni sulla parametrizzazione forzata, vedere Parametrizzazione forzata.Se OPTIMIZE FOR @variable\_name = literal_constant e OPTIMIZE FOR UNKNOWN sono utilizzati nello stesso hint per la query, Query Optimizer utilizzerà il valore literal_constant indicato per un valore specifico e UNKNOWN per i valori di variabile rimanenti. I valori vengono utilizzati durante l'ottimizzazione della query e non durante la sua esecuzione.
PARAMETERIZATION { SIMPLE | FORCED }
Specifica le regole di parametrizzazione applicate da Query Optimizer di SQL Server alla query durante la compilazione di questa.Importante L'hint per la query PARAMETERIZATION può essere specificata solo all'interno di una guida di piano e non direttamente all'interno di una query.
SIMPLE indica a Query Optimizer di tentare la parametrizzazione semplice. FORCED indica a Query Optimizer di tentare la parametrizzazione forzata. L'hint per la query PARAMETERIZATION viene utilizzato per sostituire l'impostazione corrente dell'opzione SET dell'hint di database PARAMETERIZATION all'interno di una guida di piano. Per ulteriori informazioni, vedere Definizione delle funzionalità di parametrizzazione delle query tramite guide di piano.
RECOMPILE
Indica a Motore di database di SQL Server di eliminare il piano generato per la query dopo che questa è stata eseguita e forza Query Optimizer a ricompilare un piano di query alla successiva esecuzione della stessa query. Se RECOMPILE non viene specificato, Motore di database inserisce i piani di query nella cache e li riutilizza. Durante la compilazione dei piani di query, l'hint per la query RECOMPILE utilizza i valori correnti delle variabili locali incluse nella query e, se la query è contenuta in una stored procedure, i valori correnti vengono passati ai parametri.RECOMPILE rappresenta una valida alternativa alla creazione di una stored procedure che utilizza la clausola WITH RECOMPILE quando è necessario ricompilare solo un subset di query all'interno della stored procedure, anziché l'intera stored procedure. Per ulteriori informazioni, vedere Ricompilazione di stored procedure. RECOMPILE risulta utile anche durante la creazione delle guide di piano. Per ulteriori informazioni, vedere Ottimizzazione delle query nelle applicazioni distribuite tramite le guide di piano.
ROBUST PLAN
Impone in Query Optimizer l'applicazione di un piano che funziona anche con dimensioni di riga massime, eventualmente a scapito delle prestazioni. Quando la query viene elaborata, è possibile che tabelle e operatori intermedi debbano archiviare ed elaborare righe con dimensioni maggiori rispetto a qualsiasi riga di input. Talvolta le righe possono essere talmente estese che l'operatore specificato non è in grado di elaborarle. In questi casi Motore di database genera un errore durante l'esecuzione della query. Grazie alla clausola ROBUST PLAN i piani di query in cui potrebbe verificarsi questo problema vengono ignorati da Query Optimizer.Se non è possibile implementare tale piano, viene restituito un errore anziché posticipare il rilevamento dell'errore fino all'esecuzione della query. Le righe possono includere colonne di lunghezza variabile. In Motore di database è consentito definire righe con dimensioni massime superiori alla capacità di elaborazione di Motore di database. In un'applicazione tuttavia vengono in genere archiviate righe le cui dimensioni effettive rientrano nei limiti delle capacità di elaborazione di Motore di database. Se in Motore di database viene rilevata una riga di lunghezza eccessiva, viene restituito un errore di esecuzione.
KEEP PLAN
Impone in Query Optimizer l'impostazione di una soglia di ricompilazione stimata meno restrittiva per una query. La soglia di ricompilazione stimata è il punto in corrispondenza del quale una query viene automaticamente ricompilata quando in una tabella è stato apportato il numero stabilito di modifiche a livello di colonne indicizzate mediante l'esecuzione delle istruzioni UPDATE, DELETE, MERGE o INSERT. Specificando KEEP PLAN è possibile assicurarsi che una query non venga ricompilata troppo frequentemente in caso di aggiornamenti multipli di una tabella.KEEPFIXED PLAN
Impedisce a Query Optimizer di ricompilare una query in seguito a modifiche alle statistiche. Se si specifica KEEPFIXED PLAN, una query viene ricompilata solo se lo schema delle tabelle sottostanti viene modificato oppure se in tali tabelle si esegue sp_recompile.EXPAND VIEWS
Specifica che le viste indicizzate vengono espanse e che in Query Optimizer non viene presa in considerazione alcuna vista indicizzata per la sostituzione di una parte della query. Una vista viene espansa quando nel testo della query il nome della vista viene sostituito dalla definizione della vista stessa.Con questo hint per la query viene praticamente disabilitato l'utilizzo diretto di viste indicizzate e di relativi indici nel piano di query.
La vista indicizzata non viene espansa solo se nella sezione SELECT della query viene fatto riferimento diretto alla vista e se viene specificato l'hint WITH (NOEXPAND) o WITH (NOEXPAND, INDEX( index_value [ ,...n ] ) ). Per ulteriori informazioni sull'hint per la query WITH (NOEXPAND), vedere FROM.
L'hint influisce solo sulle viste nella sezione SELECT delle istruzioni, comprese le sezioni delle istruzioni INSERT, UPDATE, MERGE e DELETE.
MAXRECURSION number
Specifica il numero massimo di ricorsioni consentite per la query corrente. number è un numero intero non negativo compreso tra 0 e 32767. Se è specificato 0, non viene applicato alcun limite. Se questa opzione non viene specificata, il limite predefinito per il server è 100.Se durante l'esecuzione della query viene raggiunto il valore specificato o predefinito per il limite MAXRECURSION, la query viene terminata e viene restituito un errore.
A causa di questo errore, verrà eseguito il rollback di tutti gli effetti dell'istruzione. Se l'istruzione è un'istruzione SELECT, è possibile che vengano restituiti risultati parziali oppure nessun risultato. È possibile che eventuali risultati parziali non includano tutte le righe nei livelli di ricorsione che superano il livello di ricorsione massimo specificato.
Per ulteriori informazioni, vedere WITH common_table_expression (Transact-SQL).
USE PLAN N**'xml_plan'**
Impone in Query Optimizer l'utilizzo di un piano di query esistente per una query specificata da 'xml_plan'. Per ulteriori informazioni, vedere Definizione dei piani di query tramite l'utilizzo forzato. USE PLAN non può essere specificato nelle istruzioni INSERT, UPDATE, MERGE o DELETE.TABLE HINT (exposed_object_name [ , <table_hint> [ [, ]...n ] ] )
Applica l'hint di tabella specificato alla tabella o alla vista che corrisponde a exposed_object_name. È consigliabile utilizzare un hint di tabella come hint per la query solo nel contesto di una guida di piano.exposed_object_name può essere uno dei seguenti riferimenti:
Quando viene utilizzato un alias per la tabella o la vista nella clausola FROM della query, exposed_object_name è l'alias.
Quando non viene utilizzato un alias, exposed_object_name è la corrispondenza esatta della tabella o della vista cui si fa riferimento nella clausola FROM. Se, ad esempio, si fa riferimento alla tabella o alla vista utilizzando un nome in due parti, exposed_object_name è lo stesso nome in due parti.
Quando viene specificato exposed_object_name senza specificare anche un hint di tabella, qualsiasi indice specificato nella query come parte di un hint di tabella per l'oggetto viene ignorato e l'utilizzo di indici è determinato da Query Optimizer. È possibile utilizzare questa tecnica per eliminare l'effetto di un hint di tabella INDEX quando non è possibile modificare la query originale. Vedere l'esempio J.
<table_hint> ::= { [ NOEXPAND ] { INDEX ( index_value [ ,...n ] ) | INDEX = ( index_value ) | FASTFIRSTROW | FORCESEEK | HOLDLOCK | NOLOCK | NOWAIT | PAGLOCK | READCOMMITTED | READCOMMITTEDLOCK | READPAST | READUNCOMMITTED | REPEATABLEREAD | ROWLOCK | SERIALIZABLE | TABLOCK | TABLOCKX | UPDLOCK | XLOCK }
Hint di tabella da applicare alla tabella o alla vista corrispondente a exposed_object_name come hint per la query. Per una descrizione di questi hint, vedere Hint di tabella (Transact-SQL).Gli hint di tabella diversi da INDEX e FORCESEEK non sono consentiti come hint per la query a meno che la query non disponga già di una clausola WITH che specifica l'hint di tabella. Per ulteriori informazioni, vedere la sezione Osservazioni.
Osservazioni
Gli hint per la query non possono essere specificati in un'istruzione INSERT, eccetto quando una clausola SELECT viene utilizzata all'interno dell'istruzione.
È possibile specificare gli hint per la query solo nella query di livello principale e non nelle sottoquery. Quando un hint di tabella viene specificato come hint per la query, l'hint può essere specificato nella query di livello superiore o in una sottoquery, tuttavia il valore specificato per exposed_object_name nella clausola TABLE HINT deve corrispondere esattamente al nome esposto nella query o nella sottoquery.
Specifica di hint di tabella come hint per la query
È consigliabile utilizzare l'hint di tabella INDEX o FORCESEEK come hint per la query solo nel contesto di una guida di piano. Le guide di piano sono utili quando non è possibile modificare la query originale, ad esempio perché si tratta di un'applicazione di terze parti. L'hint per la query specificato nella guida di piano viene aggiunto alla query prima della compilazione e dell'ottimizzazione. Per le query ad hoc, utilizzare la clausola TABLE HINT solo quando si testano istruzioni della guida di piano. Per tutte le altre query ad hoc, è consigliabile specificare tali hint solo come hint di tabella.
Se specificati come hint per la query, gli hint di tabella INDEX e FORCESEEK sono validi per gli oggetti seguenti:
Tabelle
Viste
Viste indicizzate
Espressioni di tabella comuni. L'hint deve essere specificato nell'istruzione SELECT il cui set di risultati popola l'espressione di tabella comune.
Viste a gestione dinamica
Sottoquery denominate
Gli hint di tabella INDEX e FORCESEEK possono essere specificati come hint per una query senza hint di tabella esistenti oppure possono essere utilizzati per sostituire uno o più hint INDEX o FORCESEEK esistenti nella query. Gli hint di tabella diversi da INDEX e FORCESEEK non sono consentiti come hint per la query a meno che la query non disponga già di una clausola WITH che specifica l'hint di tabella. In questo caso è necessario specificare inoltre un hint corrispondente come un hint per la query utilizzando TABLE HINT nella clausola OPTION per mantenere la semantica della query. Ad esempio, se nella query è contenuto l'hint di tabella NOLOCK, anche nella clausola OPTION nel parametro @hints della guida di piano deve essere contenuto l'hint NOLOCK. Vedere l'esempio K. Quando un hint di tabella diverso da INDEX o FORCESEEK viene specificato utilizzando TABLE HINT nella clausola OPTION senza un hint per la query corrispondente, o viceversa, viene generato l'errore 8702, che indica che la clausola OPTION può comportare la modifica della semantica della query, e la query ha esito negativo. Per ulteriori informazioni, vedere Utilizzo degli hint per le query INDEX e FORCESEEK nelle guide di piano.
Esempi
A. Utilizzo di MERGE JOIN
Nell'esempio seguente viene specificato che l'operazione JOIN nella query viene eseguita da MERGE JOIN.
USE AdventureWorks;
GO
SELECT *
FROM Sales.Customer AS c
INNER JOIN Sales.CustomerAddress AS ca ON c.CustomerID = ca.CustomerID
WHERE TerritoryID = 5
OPTION (MERGE JOIN);
GO
B. Utilizzo di OPTIMIZE FOR
Nell'esempio seguente viene indicato a Query Optimizer di utilizzare il valore 'Seattle' per la variabile locale @city\_name e di utilizzare dati statistici per determinare il valore per la variabile locale @postal\_code durante l'ottimizzazione della query.
USE AdventureWorks;
GO
DECLARE @city_name nvarchar(30);
DECLARE @postal_code nvarchar(15);
SET @city_name = 'Ascheim';
SET @postal_code = 86171;
SELECT * FROM Person.Address
WHERE City = @city_name AND PostalCode = @postal_code
OPTION ( OPTIMIZE FOR (@city_name = 'Seattle', @postal_code UNKNOWN) );
GO
C. Utilizzo di MAXRECURSION
È possibile utilizzare MAXRECURSION per evitare che un'espressione di tabella comune (CTE) ricorsiva non corretta provochi un ciclo infinito. Nell'esempio seguente viene creato intenzionalmente un ciclo infinito e viene utilizzato l'hint MAXRECURSION per limitare a due il numero di livelli di ricorsione.
USE AdventureWorks;
GO
--Creates an infinite loop
WITH cte (EmployeeID, ManagerID, Title) AS
(
SELECT EmployeeID, ManagerID, Title
FROM HumanResources.Employee
WHERE ManagerID IS NOT NULL
UNION ALL
SELECT cte.EmployeeID, cte.ManagerID, cte.Title
FROM cte
JOIN HumanResources.Employee AS e
ON cte.ManagerID = e.EmployeeID
)
--Uses MAXRECURSION to limit the recursive levels to 2
SELECT EmployeeID, ManagerID, Title
FROM cte
OPTION (MAXRECURSION 2);
GO
Dopo la correzione dell'errore del codice, l'hint MAXRECURSION non è più necessario.
D. Utilizzo di MERGE UNION
Nell'esempio seguente viene utilizzato l'hint per la query MERGE UNION.
USE AdventureWorks;
GO
SELECT *
FROM HumanResources.Employee AS e1
UNION
SELECT *
FROM HumanResources.Employee AS e2
OPTION (MERGE UNION);
GO
E. Utilizzo di HASH GROUP e FAST
Nell'esempio seguente vengono utilizzati gli hint per la query HASH GROUP e FAST.
USE AdventureWorks;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (HASH GROUP, FAST 10);
GO
F. Utilizzo di MAXDOP
Nell'esempio seguente viene utilizzato l'hint per la query MAXDOP.
USE AdventureWorks ;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (MAXDOP 2);
GO
G. Utilizzo di INDEX
Nell'esempio seguente viene utilizzato l'hint INDEX. Nel primo esempio viene specificato un singolo indice. Nel secondo esempio vengono specificati più indici per un singolo riferimento alla tabella. In entrambi gli esempi, dal momento che l'hint INDEX è applicato a una tabella che utilizza un alias, anche la clausola TABLE HINT deve specificare lo stesso alias del nome dell'oggetto esposto.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide1',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e, INDEX (IX_Employee_ManagerID)))';
GO
EXEC sp_create_plan_guide
@name = N'Guide2',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e, INDEX(PK_Employee_EmployeeID, IX_Employee_ManagerID)))';
GO
H. Utilizzo di FORCESEEK
Nell'esempio seguente viene utilizzato l'hint per la tabella FORCESEEK. Dal momento che l'hint INDEX è applicato a una tabella che utilizza un nome in due parti, anche la clausola TABLE HINT deve specificare, come nome dell'oggetto esposto, lo stesso nome in due parti.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide3',
@stmt = N'SELECT c.LastName, c.FirstName, HumanResources.Employee.Title
FROM HumanResources.Employee
JOIN Person.Contact AS c ON HumanResources.Employee.ContactID = c.ContactID
WHERE HumanResources.Employee.ManagerID = 3
ORDER BY c.LastName, c.FirstName;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT( HumanResources.Employee, FORCESEEK))';
GO
I. Utilizzo di più hint di tabella
Nell'esempio seguente vengono applicati l'hint INDEX a una tabella e l'hint FORCESEEK a un'altra.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide4',
@stmt = N'SELECT e.ManagerID, c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_ManagerID ) )
, TABLE HINT ( c, FORCESEEK) )';
GO
J. Utilizzo di TABLE HINT per eseguire l'override di un hint di tabella esistente
Nell'esempio seguente viene illustrato come utilizzare l'hint TABLE HINT senza specificare un hint per eseguire l'override del comportamento dell'hint di tabella INDEX specificato nella clausola FROM della query.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide5',
@stmt = N'SELECT e.ManagerID, c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e WITH (INDEX (IX_Employee_ManagerID))
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e))';
GO
K. Specifica di hint di tabella che influiscono sulla semantica
Nella query dell'esempio seguente sono contenuti due hint di tabella, NOLOCK che influisce sulla semantica e INDEX che non influisce sulla semantica. Per mantenere la semantica della query, l'hint NOLOCK viene specificato nella clausola OPTIONS della guida di piano. Oltre all'hint NOLOCK vengono specificati gli hint INDEX e FORCESEEK, che sostituiscono l'hint INDEX che non influisce sulla semantica nella query quando l'istruzione viene compilata e ottimizzata.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide6',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
WITH (NOLOCK, INDEX (PK_Employee_EmployeeID))
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_ManagerID) , NOLOCK, FORCESEEK ))';
GO
Nell'esempio seguente viene illustrato un metodo alternativo per mantenere la semantica della query e consentire a Query Optimizer di scegliere un indice diverso da quello specificato nell'hint di tabella. A tale scopo occorre specificare l'hint NOLOCK nella clausola OPTIONS (poiché influisce sulla semantica) e la parola chiave TABLE HINT con solo un riferimento alla tabella e nessun hint INDEX.
USE AdventureWorks;
GO
EXEC sp_create_plan_guide
@name = N'Guide7',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
WITH (NOLOCK, INDEX (PK_Employee_EmployeeID))
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, NOLOCK))';
GO