Hint di tabella (Transact-SQL)

Gli hint di tabella consentono di modificare il comportamento predefinito di Query Optimizer per la durata dell'istruzione DML (Data Manipulation Language) specificando un metodo di blocco, uno o più indici, un'operazione di elaborazione di query, quale una scansione di tabella (Table Scan) o una ricerca nell'indice (Index Seek), oppure altre opzioni.

Nota di attenzioneAttenzione

Poiché Query Optimizer di SQL Server consente in genere di selezionare il piano di esecuzione migliore per una query, gli hint devono essere utilizzati solo se strettamente necessario da sviluppatori e amministratori di database esperti.

Si applica a:

DELETE

INSERT

SELECT

UPDATE

MERGE

Icona di collegamento a un argomentoConvenzioni della sintassi Transact-SQL

Sintassi

WITH ( <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 
} 

<table_hint_limited> ::=
{
    KEEPIDENTITY 
  | KEEPDEFAULTS 
  | FASTFIRSTROW 

  | HOLDLOCK 
  | IGNORE_CONSTRAINTS 
  | IGNORE_TRIGGERS 
  | NOWAIT
  | PAGLOCK 
  | READCOMMITTED 
  | READCOMMITTEDLOCK 
  | READPAST 
  | REPEATABLEREAD 
  | ROWLOCK 
  | SERIALIZABLE 
  | TABLOCK 
  | TABLOCKX 
  | UPDLOCK 
  | XLOCK 
} 

Argomenti

  • WITH ( <table_hint> ) [ [ , ]...n ]
    Con alcune eccezioni, gli hint di tabella sono supportati nella clausola FROM solo se vengono specificati con la parola chiave WITH. Tali hint devono inoltre essere racchiusi tra parentesi.

    Nota importanteImportante

    L'omissione della parola chiave WITH è una funzionalità obsoleta: Questa caratteristica verrà rimossa a partire da una delle prossime versioni di Microsoft SQL Server. Evitare di utilizzare questa funzionalità in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata.

    Gli hint di tabella riportati di seguito sono supportati sia con che senza la parola chiave WITH: NOLOCK, READUNCOMMITTED, UPDLOCK, REPEATABLEREAD, SERIALIZABLE, READCOMMITTED, FASTFIRSTROW, TABLOCK, TABLOCKX, PAGLOCK, ROWLOCK, NOWAIT, READPAST, XLOCK e NOEXPAND. Se vengono specificati senza la parola chiave WITH, questi hint devono essere specificati da soli. Ad esempio:

    FROM t (TABLOCK)
    

    Se l'hint viene specificato con un'altra opzione, è necessario utilizzare la parola chiave WITH:

    FROM t WITH (TABLOCK, INDEX(myindex))
    

    Si consiglia di separare gli hint di tabella tramite virgole.

    Nota importanteImportante

    L'utilizzo di spazi al posto delle virgole per separare gli hint è una funzionalità obsoleta: Questa caratteristica verrà rimossa a partire da una delle prossime versioni di Microsoft SQL Server. Non utilizzare questa caratteristica in un nuovo progetto di sviluppo e modificare non appena possibile le applicazioni in cui è attualmente implementata.

    Queste restrizioni sono valide quando gli hint vengono utilizzati in query eseguite su database con livello di compatibilità maggiore o uguale a 90.

  • NOEXPAND
    Specifica che qualsiasi vista indicizzata non verrà espansa per accedere alle tabelle sottostanti quando Query Optimizer elabora la query. In Query Optimizer la vista viene gestita come una tabella con indici cluster. L'hint NOEXPAND è applicabile solo alle viste indicizzate. Per ulteriori informazioni, vedere la sezione Osservazioni.

  • INDEX ( index_value [ ,... n ] ) | INDEX = ( index_value )
    La sintassi INDEX() specifica i nomi o gli ID di uno o più indici che devono essere utilizzati in Query Optimizer quando viene elaborata l'istruzione. La sintassi alternativa INDEX = specifica un singolo valore di indice. È possibile specificare solo un hint per l'indice per ogni tabella.

    Se esiste un indice cluster, INDEX(0) attiva una scansione degli indici cluster, mentre INDEX(1) esegue una scansione o una ricerca degli indici cluster. Se non esiste alcun indice cluster, INDEX(0) attiva una scansione di tabella, mentre INDEX(1) viene interpretato come errore.

    Se in un unico elenco di hint vengono utilizzati più indici, gli indici duplicati vengono ignorati, mentre gli altri indici vengono utilizzati per recuperare le righe della tabella. L'ordine degli indici nell'hint è significativo. Un hint con più indici impone inoltre il collegamento degli indici tramite operatore AND e Query Optimizer applica il numero massimo di condizioni possibili a ogni indice a cui viene effettuato l'accesso. Se la raccolta di indici con hint non include tutte le colonne a cui la query fa riferimento, viene eseguita un'operazione di recupero delle colonne rimanenti dopo che tutte le colonne indicizzate sono state recuperate dal Motore di database di SQL Server.

    [!NOTA]

    Se in una tabella dei fatti in un join a stella viene utilizzato un hint per l'indice che fa riferimento a più indici, l'hint per l'indice viene ignorato e verrà restituito un messaggio di avviso. Non è inoltre consentito il collegamento degli indici tramite OR per una tabella per la quale è stato specificato un hint per l'indice.

    Un hint di tabella può includere al massimo 250 indici non cluster.

  • KEEPIDENTITY
    Applicabile solo in un'istruzione INSERT se viene utilizzata l'opzione BULK con OPENROWSET.

    Specifica che i valori Identity presenti nel file di dati importato devono essere utilizzati per la colonna Identity. Se KEEPIDENTITY viene omesso, i valori Identity per questa colonna vengono verificati ma non importati e Query Optimizer assegna automaticamente valori univoci in base ai valori di inizializzazione e di incremento specificati in fase di creazione della tabella.

    Nota importanteImportante

    Se il file di dati non contiene valori per la colonna Identity nella tabella o nella vista, tale colonna deve essere ignorata, a meno che non sia l'ultima colonna della tabella. Per ulteriori informazioni, vedere Utilizzo di un file di formato per escludere un campo di dati. Se una colonna Identity viene ignorata correttamente, Query Optimizer assegna automaticamente valori univoci per la colonna Identity nelle righe importate della tabella.

    Per un esempio di utilizzo di questo hint in un'istruzione INSERT ... SELECT * FROM OPENROWSET(BULK...), vedere Mantenimento dei valori Identity durante l'importazione bulk dei dati.

    Per ulteriori informazioni sul controllo del valore Identity per una tabella, vedere DBCC CHECKIDENT (Transact-SQL).

  • KEEPDEFAULTS
    Applicabile solo in un'istruzione INSERT se viene utilizzata l'opzione BULK con OPENROWSET.

    Specifica l'inserimento di un valore predefinito per la colonna della tabella, se disponibile, al posto del valore NULL quando nel record di dati non è presente un valore per la colonna.

    Per un esempio di utilizzo di questo hint in un'istruzione INSERT ... SELECT * FROM OPENROWSET(BULK...), vedere Mantenimento dei valori Null o utilizzo dei valori predefiniti durante un'importazione bulk.

  • FASTFIRSTROW
    Equivale a OPTION (FAST 1). Per ulteriori informazioni, vedere Hint per la query (Transact-SQL).

    Nota importanteImportante

    Questa caratteristica verrà rimossa a partire dalla prossima versione di Microsoft SQL Server. Non utilizzare questa caratteristica in un nuovo progetto di sviluppo e modificare non appena possibile le applicazioni in cui è attualmente implementata.

  • FORCESEEK
    Specifica che Query Optimizer deve utilizzare solo un'operazione di ricerca nell'indice come percorso di accesso ai dati della tabella o della vista a cui si fa riferimento nella query.

    FORCESEEK si applica alle operazioni Clustered Index Seek e Nonclustered Index Seek. Questo argomento può essere specificato per qualsiasi tabella o vista nella clausola FROM di un'istruzione SELECT e nella clausola FROM <table_source> di un'istruzione UPDATE, MERGE o DELETE.

    È possibile specificare FORCESEEK con o senza un hint per l'indice. Quando viene specificato in combinazione con un hint per l'indice, in Query Optimizer vengono considerati solo i percorsi di accesso alla ricerca tramite l'indice specificato. Se con FORCESEEK non viene trovato alcun piano, viene restituito l'errore 8622. Per ulteriori informazioni, vedere Utilizzo dell'hint di tabella FORCESEEK.

  • HOLDLOCK
    Equivale a SERIALIZABLE. Per ulteriori informazioni, vedere la sezione SERIALIZABLE di seguito in questo argomento. HOLDLOCK si applica solo alla tabella o alla vista per la quale è stato specificato e solo per la durata della transazione definita dall'istruzione in cui è utilizzato. Non è possibile utilizzare l'argomento HOLDLOCK in un'istruzione SELECT che include l'opzione FOR BROWSE.

  • IGNORE_CONSTRAINTS
    Applicabile solo in un'istruzione INSERT se viene utilizzata l'opzione BULK con OPENROWSET.

    Specifica che qualsiasi vincolo sulla tabella verrà ignorato dall'operazione di importazione bulk. Per impostazione predefinita, l'istruzione INSERT controlla i vincoli CHECK e FOREIGN KEY. Se si specifica IGNORE_CONSTRAINTS per un'operazione di importazione bulk, l'istruzione INSERT deve ignorare tali vincoli in una tabella di destinazione. Si noti che non è possibile disattivare i vincoli UNIQUE, PRIMARY KEY o NOT NULL.

    Se i dati di input contengono righe che violano i vincoli, potrebbe essere necessario disattivare i vincoli CHECK e FOREIGN KEY. Disattivando i vincoli CHECK e FOREIGN KEY, è possibile importare i dati e quindi utilizzare istruzioni Transact-SQL per pulire i dati.

    Quando, tuttavia, i vincoli CHECK e FOREIGN KEY vengono ignorati, ogni vincolo ignorato nella tabella viene contrassegnato come is_not_trusted nella vista del catalogo sys.check_constraints o sys.foreign_keys dopo l'operazione. A un certo punto sarà necessario controllare i vincoli nell'intera tabella. Se la tabella non è vuota prima dell'operazione di importazione bulk, l'impegno per la riconvalida dei vincoli può essere superiore all'impegno per l'applicazione dei vincoli CHECK e FOREIGN KEY ai dati incrementali.

  • IGNORE_TRIGGERS
    Applicabile solo in un'istruzione INSERT se viene utilizzata l'opzione BULK con OPENROWSET.

    Specifica che qualsiasi trigger definito sulla tabella verrà ignorato dall'operazione di importazione bulk. Per impostazione predefinita, l'istruzione INSERT applica i trigger.

    Utilizzare l'argomento IGNORE_TRIGGERS solo se l'applicazione non dipende dai trigger e l'ottimizzazione delle prestazioni è un fattore importante.

  • NOLOCK
    Equivale a READUNCOMMITTED. Per ulteriori informazioni, vedere la sezione READUNCOMMITTED di seguito in questo argomento.

    [!NOTA]

    Per le istruzioni UPDATE e DELETE: Questa caratteristica verrà rimossa a partire da una delle prossime versioni di Microsoft SQL Server. Evitare di utilizzare questa funzionalità in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata.

  • NOWAIT
    Imposta il Motore di database in modo che venga restituito un messaggio non appena viene rilevato un blocco nella tabella. NOWAIT equivale a specificare SET LOCK_TIMEOUT 0 per una tabella specifica.

  • PAGLOCK
    Acquisisce i blocchi di pagina dove in genere vengono acquisiti i singoli blocchi su righe o chiavi oppure dove in genere viene acquisito un singolo blocco a livello di tabella. Per impostazione predefinita, viene utilizzato la modalità di blocco appropriata per l'operazione specifica. Se viene specificato nelle transazioni operative al livello di isolamento SNAPSHOT, i blocchi di pagina vengono acquisiti solo se PAGLOCK è combinato con altri hint di tabella che richiedono i blocchi, ad esempio UPDLOCK e HOLDLOCK.

  • READCOMMITTED
    Specifica la conformità delle operazioni di lettura con le regole relative al livello di isolamento READ COMMITTED mediante l'utilizzo dei blocchi o del controllo delle versioni delle righe. Se l'opzione di database READ_COMMITTED_SNAPSHOT è impostata su OFF, il Motore di database acquisisce blocchi condivisi durante la lettura dei dati e rilascia tali blocchi al completamento dell'operazione di lettura. Se l'opzione di database READ_COMMITTED_SNAPSHOT è impostata su ON, Motore di database non acquisisce i blocchi e utilizza il controllo delle versioni delle righe. Per ulteriori informazioni sui livelli di isolamento, vedere SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

    [!NOTA]

    Per le istruzioni UPDATE e DELETE: Questa caratteristica verrà rimossa a partire da una delle prossime versioni di Microsoft SQL Server. Evitare di utilizzare questa funzionalità in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata.

  • READCOMMITTEDLOCK
    Specifica la conformità delle operazioni di lettura con le regole relative al livello di isolamento READ COMMITTED mediante l'utilizzo dei blocchi. Motore di database acquisisce i blocchi condivisi durante la lettura dei dati e li rilascia al completamento dell'operazione di lettura indipendentemente dalle impostazioni dell'opzione di database READ_COMMITTED_SNAPSHOT. Per ulteriori informazioni sui livelli di isolamento, vedere SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

  • READPAST
    Specifica che il Motore di database non leggerà le righe bloccate da altre transazioni. Nella maggior parte dei casi, ciò è applicabile anche alle pagine. Se si specifica READPAST, vengono ignorati i blocchi sia a livello di riga che a livello di pagina. Il Motore di database ignora le righe o le pagine anziché bloccare la transazione corrente finché i blocchi non vengono rilasciati. Si supponga, ad esempio, che la tabella T1 contenga una sola colonna integer con i valori 1, 2, 3, 4, 5. Se la transazione A modifica il valore da 3 a 8 senza eseguire il commit, l'istruzione SELECT * FROM T1 (READPAST) restituisce i valori 1, 2, 4, 5. READPAST è utilizzato principalmente per ridurre la contesa dei blocchi durante l'implementazione di una coda di elaborazione che utilizza una tabella SQL Server. Un agente di lettura coda che utilizza l'argomento READPAST ignora le voci della coda bloccate da altre transazioni e passa alla successiva voce disponibile senza attendere il rilascio dei blocchi da parte delle altre transazioni.

    È possibile specificare l'argomento READPAST per qualsiasi tabella a cui viene fatto riferimento in un'istruzione UPDATE o DELETE e per qualsiasi tabella a cui viene fatto riferimento in una clausola FROM. Se specificato in un'istruzione UPDATE, l'argomento READPAST viene applicato solo durante la lettura dei dati per l'identificazione dei record da aggiornare, indipendentemente dalla posizione in cui è stato specificato all'intero dell'istruzione. Non è possibile specificare l'argomento READPAST per le tabelle nella clausola INTO di un'istruzione INSERT. Le operazioni di lettura che utilizzano l'argomento READPAST non applicano blocchi. È possibile che le operazioni di aggiornamento o eliminazione che utilizzano l'argomento READPAST applichino blocchi durante la lettura delle chiavi esterne o delle viste indicizzate oppure durante la modifica degli indici secondari.

    L'argomento READPAST può essere specificato solo nelle transazioni operative ai livelli di isolamento READ COMMITTED o REPEATABLE READ. Se viene specificato nelle transazioni operative al livello di isolamento SNAPSHOT, è necessario combinare READPAST con altri hint di tabella che richiedono i blocchi, ad esempio UPDLOCK e HOLDLOCK.

    L'hint di tabella READPAST non può essere specificato quando l'opzione di database READ_COMMITTED_SNAPSHOT è impostata su ON e una delle condizioni seguenti è vera.

    • Il livello di isolamento delle transazioni della sessione è READ COMMITTED.

    • L'hint di tabella READCOMMITTED viene specificato anche nella query.

    Per specificare l'hint READPAST in questi casi, rimuovere l'hint di tabella READCOMMITTED, se presente, e includere l'hint di tabella READCOMMITTEDLOCK nella query.

  • READUNCOMMITTED
    Indica che le letture dirty sono consentite. Non viene acquisito alcun blocco condiviso per impedire alle altre transazioni di modificare i dati letti dalla transazione corrente. I blocchi esclusivi impostati dalle altre transazioni non impediscono alla transazione corrente di leggere i dati bloccati. Le letture dirty possono provocare un livello più alto di concorrenza a discapito della lettura delle modifiche dei dati per le quali le altre transazioni eseguiranno il rollback. Di conseguenza, è possibile che vengano generati errori per la transazione, che vengano forniti agli utenti dati di cui non è mai stato eseguito il commit oppure che gli utenti visualizzino i record due volte o che non li visualizzino affatto. Per ulteriori informazioni su letture dirty, letture non ripetibili e letture fantasma, vedere Effetti della concorrenza.

    Gli hint READUNCOMMITTED e NOLOCK sono applicabili soltanto a blocchi a livello di dati. Tutte le query, incluse quelle con hint READUNCOMMITTED e NOLOCK, acquisiscono blocchi di stabilità dello schema (Sch-S) durante la compilazione e l'esecuzione. Per questo motivo, le query vengono bloccate quando una transazione simultanea mantiene attivo un blocco di modifica dello schema sulla tabella. Un'operazione DDL (Data Definition Language), ad esempio, acquisisce un blocco Sch-M prima di modificare le informazioni sullo schema della tabella. Tutte le query simultanee che tentano di acquisire un blocco Sch-S, incluse quelle in esecuzione con hint READUNCOMMITTED o NOLOCK, vengono bloccate. Una query con blocco Sch-S blocca invece le transazioni simultanee che tentano di acquisire un blocco Sch-M. Per ulteriori informazioni sul comportamento di blocco, vedere Compatibilità tra blocchi (Motore di database).

    Non è possibile specificare READUNCOMMITTED e NOLOCK per le tabelle modificate da operazioni di inserimento, aggiornamento o eliminazione. Query Optimizer di SQL Server ignora gli hint READUNCOMMITTED e NOLOCK della clausola FROM applicata alla tabella di destinazione di un'istruzione UPDATE o DELETE.

    [!NOTA]

    In una versione futura di SQL Server verrà rimosso il supporto per l'utilizzo degli hint READUNCOMMITTED e NOLOCK nella clausola FROM per la tabella di destinazione di un'istruzione UPDATE o DELETE. Evitare quindi di utilizzare questi hint in questo contesto nei nuovi progetti di sviluppo e pianificare la modifica delle applicazioni in cui sono attualmente utilizzati.

    È possibile ridurre al minimo la contesa tra blocchi proteggendo nello stesso tempo le transazioni da letture dirty di modifiche dei dati di cui non è stato eseguito il commit utilizzando una delle impostazioni seguenti:

    • Livello di isolamento READ COMMITTED con l'opzione di database READ_COMMITTED_SNAPSHOT impostata su ON.

    • Livello di isolamento SNAPSHOT.

    Per ulteriori informazioni sui livelli di isolamento, vedere SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

    [!NOTA]

    Se si verificano errori 601 quando è specificata l'opzione READUNCOMMITTED, risolverli come errori di deadlock (1205), quindi provare a rieseguire l'istruzione.

  • REPEATABLEREAD
    Specifica che viene eseguita una scansione con la stessa semantica di blocco di una transazione eseguita con un livello di isolamento REPEATABLE READ. Per ulteriori informazioni sui livelli di isolamento, vedere SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

  • ROWLOCK
    Specifica l'acquisizione dei blocchi di riga quando in genere vengono acquisiti i blocchi di pagina o i blocchi a livello di tabella. Se viene specificato nelle transazioni operative al livello di isolamento SNAPSHOT, i blocchi di riga vengono acquisiti solo se ROWLOCK è combinato con altri hint di tabella che richiedono i blocchi, ad esempio UPDLOCK e HOLDLOCK.

  • SERIALIZABLE
    Equivale a HOLDLOCK. Rende i blocchi condivisi più restrittivi mantenendoli attivi fino al completamento di una transazione anziché rilasciarli non appena la tabella o la pagina dei dati richiesta non è più necessaria indipendentemente dal completamento della transazione. La scansione viene eseguita con la stessa semantica di una transazione eseguita con il livello di isolamento SERIALIZABLE. Per ulteriori informazioni sui livelli di isolamento, vedere SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

  • TABLOCK
    Specifica l'acquisizione di un blocco condiviso sulla tabella, che verrà mantenuto attivo fino al termine dell'istruzione. Se si specifica anche HOLDLOCK, il blocco di tabella condiviso viene mantenuto attivo fino al termine della transazione.

    Quando si importano dati in un heap tramite l'istruzione INSERT INTO <target_table> SELECT <columns> FROM <source_table>, è possibile abilitare la registrazione ottimizzata e i blocchi per l'istruzione specificando l'hint TABLOCK per la tabella di destinazione. Il modello di recupero del database deve inoltre essere impostato sul modello con registrazione minima o con registrazione minima delle operazioni bulk. Per ulteriori informazioni, vedere INSERT (Transact-SQL).

    Se utilizzato in combinazione con il provider di set di righe con lettura bulk OPENROWSET per importare dati in una tabella, TABLOCK consente a più client di caricare simultaneamente i dati nella tabella di destinazione ottimizzandone la registrazione e i blocchi. Per ulteriori informazioni, vedere Prerequisiti per la registrazione minima nell'importazione bulk.

  • TABLOCKX
    Specifica l'acquisizione di un blocco esclusivo sulla tabella.

  • UPDLOCK
    Specifica che è necessario richiedere i blocchi di aggiornamento, i quali dovranno essere mantenuti attivi fino al completamento della transazione.

  • XLOCK
    Specifica che è necessario richiedere i blocchi esclusivi, i quali dovranno essere mantenuti attivi fino al completamento della transazione. Se specificato in combinazione con ROWLOCK, PAGLOCK o TABLOCK, i blocchi esclusivi vengono applicati al livello di granularità appropriato.

Osservazioni

Gli hint di tabella vengono ignorati se il piano di query non accede alla tabella. Ciò si verifica se Query Optimizer non accede esplicitamente alla tabella oppure perché viene invece eseguito l'accesso a una vista indicizzata. In questo secondo caso è possibile impedire l'accesso a una vista indicizzata utilizzando l'hint per la query OPTION (EXPAND VIEWS).

Tutti gli hint di blocco vengono distribuiti a tutte le tabelle e viste a cui accede il piano di query, incluse tabelle e viste di riferimento in una vista. SQL Server esegue inoltre le relative verifiche di consistenza dei blocchi.

È possibile che gli hint di blocco ROWLOCK, UPDLOCK e AND XLOCK che acquisiscono blocchi a livello di riga applichino blocchi alle chiavi di indice anziché alle righe di dati effettive. Se, ad esempio, una tabella include un indice non cluster e un'istruzione SELECT che utilizza un hint di blocco viene gestita da un indice di copertura, viene acquisito un blocco sulla chiave dell'indice di copertura anziché sulla riga di dati nella tabella di base.

Se una tabella include colonne calcolate e le colonne calcolate vengono calcolate in base a espressioni o funzioni che accedono a colonne in altre tabelle, su tali tabelle non verranno utilizzati gli hint di tabella. Ciò significa che gli hint di tabella non vengono propagati. Ad esempio, un hint di tabella NOLOCK è specificato in una tabella della query che include colonne calcolate tramite una combinazione di espressioni e funzioni che accedono alle colonne di un'altra tabella. Le tabelle a cui le espressioni e le funzioni fanno riferimento non utilizzano l'hint di tabella NOLOCK durante l'accesso.

Per ogni tabella nella clausola FROM in SQL Server non è consentito impostare più di un hint di tabella appartenente a ognuno dei gruppi seguenti:

  • Hint di granularità: PAGLOCK, NOLOCK, ROWLOCK, TABLOCK o TABLOCKX.

  • Hint del livello di isolamento: HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE.

Hint per l'indice filtrato

È possibile utilizare un hint per l'indice filtrato come hint di tabella; se tuttavia tale indice non include tutte le righe selezionate dalla query, in Query Optimizer viene generato l'errore 8622. Di seguito viene fornito un esempio di hint per l'indice filtrato non valido. Nell'esempio viene creato l'indice filtrato FIBillOfMaterialsWithComponentID, che viene quindi utilizzato come hint per l'indice per un'istruzione SELECT. Il predicato dell'indice filtrato include righe di dati per gli elementi ComponentID 533, 324 e 753. Anche il predicato della query include righe di dati per gli elementi ComponentID 533, 324 e 753, ma estende il set di risultati in modo da includere gli elementi ComponentID 855 e 924, non inclusi nell'indice filtrato. In Query Optimizer l'hint per l'indice filtrato non può pertanto essere utilizzato e viene generato l'errore 8622. Per ulteriori informazioni, vedere Linee guida per la progettazione di indici filtrati.

USE AdventureWorks;
GO
IF EXISTS (SELECT name FROM sys.indexes
    WHERE name = N'FIBillOfMaterialsWithComponentID' 
    AND object_id = OBJECT_ID(N'Production.BillOfMaterials'))
DROP INDEX FIBillOfMaterialsWithComponentID
    ON Production.BillOfMaterials;
GO
CREATE NONCLUSTERED INDEX "FIBillOfMaterialsWithComponentID"
    ON Production.BillOfMaterials (ComponentID, StartDate, EndDate)
    WHERE ComponentID IN (533, 324, 753);
GO
SELECT StartDate, ComponentID FROM Production.BillOfMaterials
    WITH( INDEX (FIBillOfMaterialsWithComponentID) )
    WHERE ComponentID in (533, 324, 753, 855, 924);
GO

In Query Optimizer un hint per l'indice non viene considerato se le opzioni SET non includono i valori necessari per gli indici filtrati. Per ulteriori informazioni, vedere CREATE INDEX (Transact-SQL).

Utilizzo di NOEXPAND

L'hint NOEXPAND è applicabile solo alle viste indicizzate, ovvero alle viste in cui è stato creato un indice cluster univoco. Query Optimizer utilizza l'indice nella vista se una query include riferimenti a colonne disponibili sia in una vista indicizzata che nelle tabelle di base e viene determinato che l'utilizzo della vista indicizzata rappresenta il metodo migliore per l'esecuzione della query. Questa funzione viene definita corrispondenza delle viste indicizzate ed è supportata solo in SQL Server Enterprise Edition e Developer Edition.

Affinché Query Optimizer utilizzi le viste indicizzate oppure una vista indicizzata a cui viene fatto riferimento tramite l'hint NOEXPAND per l'esecuzione della corrispondenza, le opzioni SET seguenti devono essere impostate su ON:

ANSI_NULLS

ANSI_WARNINGS

CONCAT_NULL_YIELDS_NULL

ANSI_PADDING

ARITHABORT1

QUOTED_IDENTIFIERS

1 ARITHABORT viene impostata in modo implicito su ON se ANSI_WARNINGS è impostata su ON. Non sarà pertanto necessario modificare manualmente questa impostazione.

L'opzione NUMERIC_ROUNDABORT deve invece essere impostata su OFF.

Per imporre l'utilizzo di un indice per una vista indicizzata in Query Optimizer, è necessario specificare l'opzione NOEXPAND. È possibile utilizzare questo hint solo se la vista è specificata anche nella query. In SQL Server non è disponibile un hint per imporre l'utilizzo di una vista indicizzata specifica in una query in cui tale vista non viene specificata direttamente nella clausola FROM. In Query Optimizer viene tuttavia valutata la possibilità di utilizzare le viste indicizzate, anche se non sono presenti riferimenti diretti a tali viste all'interno della query.

Per ulteriori informazioni, vedere Risoluzione di indici nelle viste.

Utilizzo di un hint di tabella come hint per la query

Gli hint di tabella possono anche essere specificati come hint per la query utilizzando la clausola OPTION (TABLE HINT). È consigliabile utilizzare un hint di tabella come hint per la query solo nel contesto di una guida di piano. Per le query ad hoc, specificare questi hint solo come hint di tabella. Per ulteriori informazioni, vedere Hint per la query (Transact-SQL).

Autorizzazioni

Gli hint KEEPIDENTITY, IGNORE_CONSTRAINTS e IGNORE_TRIGGERS richiedono l'autorizzazione ALTER sulla tabella.

Esempi

A. Utilizzo dell'hint TABLOCK per specificare un metodo di blocco

Nell'esempio seguente viene impostata l'acquisizione di un blocco condiviso sulla tabella Production.Product. Tale blocco viene mantenuto attivo fino al termine dell'istruzione UPDATE.

USE AdventureWorks;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO

B. Utilizzo dell'hint FORCESEEK per specificare un'operazione di ricerca nell'indice

Nell'esempio seguente viene utilizzato l'hint FORCESEEK per fare in modo che in Query Optimizer venga eseguita un'operazione di ricerca nell'indice nella tabella Sales.SalesOrderDetail.

USE AdventureWorks;
GO
SELECT *
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d WITH (FORCESEEK)
    ON h.SalesOrderID = d.SalesOrderID 
WHERE h.TotalDue > 100
AND (d.OrderQty > 5 OR d.LineTotal < 1000.00);
GO