Risoluzione di indici nelle viste

Come per qualsiasi indice, in SQL Server vengono utilizzate viste indicizzate nel piano della query solo se tramite Query Optimizer viene determinato che tale operazione è vantaggiosa.

Le viste indicizzate possono essere create con qualsiasi versione di SQL Server. In SQL Server Enterprise Edition la vista indicizzata viene automaticamente presa in considerazione in Query Optimizer. Per utilizzare una vista indicizzata con le altre versioni, è necessario utilizzare l'hint di tabella NOEXPAND.

In Query Optimizer di SQL Server viene utilizzata una vista indicizzata se vengono soddisfatte le condizioni seguenti:

  • Le opzioni relative alla sessione indicate di seguito sono impostate su ON:

    • ANSI_NULLS

    • ANSI_PADDING

    • ANSI_WARNINGS

    • ARITHABORT

    • CONCAT_NULL_YIELDS_NULL

    • QUOTED_IDENTIFIER

    • L'opzione NUMERIC_ROUNDABORT relativa alla sessione è impostata su OFF.

  • In Query Optimizer viene trovata una corrispondenza tra le colonne dell'indice della vista e gli elementi della query, tra cui:

    • Predicati relativi a condizioni di ricerca nella clausola WHERE

    • Operazioni di join

    • Funzioni di aggregazione

    • Clausole GROUP BY

    • Riferimenti alla tabella

  • Il costo stimato necessario per l'utilizzo dell'indice è inferiore a quello di qualsiasi altro meccanismo di accesso considerato in Query Optimizer.

  • Ogni tabella a cui si fa riferimento nella query, direttamente oppure espandendo una vista per accedere alle tabelle sottostanti, corrispondente a un riferimento alla tabella nella vista indicizzata, deve disporre dello stesso set di hint ad essa applicato nella query.

    [!NOTA]

    Gli hint READCOMMITTED e READCOMMITTEDLOCK sono sempre considerati diversi in questo contesto, indipendentemente dal livello corrente di isolamento delle transazioni.

Ad eccezione dei requisiti relativi alle opzioni SET e agli hint di tabella, si tratta delle stesse regole utilizzate da Query Optimizer per determinare se l'indice di una tabella copre una query. Per utilizzare una vista indicizzata, non è necessario specificare nient'altro nella query.

Non è necessario che una query faccia riferimento in modo esplicito a una vista indicizzata nella clausola FROM affinché in Query Optimizer venga utilizzata la vista indicizzata. Se la query include riferimenti alle colonne delle tabelle di base incluse anche nella vista indicizzata e tramite Query Optimizer viene determinato che l'utilizzo della vista indicizzata è il meccanismo di accesso più economico, in Query Optimizer viene scelta la vista indicizzata con modalità analoghe a quelle utilizzate per scegliere gli indici delle tabelle di base a cui non viene fatto riferimento diretto in una query. Query Optimizer potrebbe scegliere la vista anche se include colonne a cui non fa riferimento la query, a condizione che la vista stessa rappresenti la soluzione più economica ai fini della copertura di una o più colonne specificate nella query.

Query Optimizer elabora le viste indicizzate a cui fa riferimento la clausola FROM come viste standard. Tramite Query Optimizer la definizione della vista viene espansa nella query all'inizio del processo di ottimizzazione. Viene quindi eseguita la ricerca della corrispondenza nella vista indicizzata. La vista indicizzata potrebbe essere utilizzata nel piano di esecuzione finale selezionato da Query Optimizer oppure il piano può ottenere dalla vista i dati necessari accedendo alle tabelle di base a cui la vista fa riferimento. Tramite Query Optimizer viene scelta l'alternativa con il costo inferiore.

Utilizzo di hint con viste indicizzate

È possibile impedire l'utilizzo delle viste indicizzate da parte di una query utilizzando l'hint per la query EXPAND VIEWS oppure è possibile utilizzare l'hint di tabella NOEXPAND per fare in modo che venga utilizzato un indice per una vista indicizzata specificata nella clausola FROM di una query. È tuttavia consigliabile lasciar determinare in modo dinamico a Query Optimizer i metodi di accesso migliori da utilizzare per ogni query. Limitare l'utilizzo degli hint EXPAND e NOEXPAND a casi specifici per i quali si è verificato che in tal modo è possibile ottenere un miglioramento significativo delle prestazioni.

L'opzione EXPAND VIEWS specifica che in Query Optimizer non verranno utilizzati indici delle viste per l'intera query.

Se per una vista viene specificata l'opzione NOEXPAND, tramite Query Optimizer viene valuta l'opportunità di utilizzare gli indici definiti per la vista. Se l'opzione NOEXPAND viene specificata con la clausola facoltativa INDEX(), tramite Query Optimizer verranno utilizzati gli indici specificati. L'opzione NOEXPAND può essere specificata solo per le viste indicizzate e non è supportata nelle viste non indicizzate.

Quando non viene specificata né l'opzione NOEXPAND né EXPAND VIEWS in una query contenente una vista, la vista viene espansa per accedere alle tabelle sottostanti. Se la query che compone la vista contiene hint di tabella, tali hint vengono propagati alle tabelle sottostanti. Per ulteriori informazioni su questo processo, vedere Risoluzione delle viste. Se i set di hint presenti nelle tabelle sottostanti della vista sono identici tra loro, la query può essere utilizzata per la ricerca della corrispondenza con una vista indicizzata. La maggior parte delle volte questi hint corrispondono tra loro in quanto vengono ereditati direttamente dalla vista. Se. tuttavia, la query fa riferimento a tabelle anziché a viste e gli hint applicati direttamente a tali tabelle non sono identici, la query non può essere utilizzata per la ricerca della corrispondenza con una vista indicizzata. Se gli hint INDEX, PAGLOCK, ROWLOCK, TABLOCKX, UPDLOCK o XLOCK vengono applicati a tabelle a cui fa riferimento la query dopo l'espansione della vista, la query non può essere utilizzata per la ricerca della corrispondenza con una vista indicizzata.

Se un hint di tabella nel formato INDEX (index_val[ ,...n] ) fa riferimento a una vista in una query e non viene specificato anche l'hint NOEXPAND, l'hint per l'indice viene ignorato. Per specificare l'utilizzo di un determinato indice, usare l'opzione NOEXPAND.

In genere, quando tramite Query Optimizer viene trovata una corrispondenza tra una vista indicizzata e una query, eventuali hint specificati nelle tabelle o nelle viste nella query vengono applicati direttamente alla vista indicizzata. Se tramite Query Optimizer viene scelto di non utilizzare una vista indicizzata, eventuali hint vengono propagati direttamente alle tabelle a cui viene fatto riferimento nella vista. Per ulteriori informazioni, vedere Risoluzione delle viste. Questa propagazione non riguarda gli hint di join, che vengono applicati solo nella relativa posizione originale nella query. Gli hint di join non vengono presi in considerazione da Query Optimizer durante la ricerca della corrispondenza tra query e viste indicizzate. Se in un piano della query viene utilizzata una vista indicizzata che corrisponde a una parte di una query contenente un hint di join, tale hint non viene utilizzato nel piano.

In SQL Server 2008 non possono essere presenti hint nelle definizioni delle viste indicizzate. Nella modalità di compatibilità 80 e superiore, in SQL Server vengono ignorati gli hint contenuti nelle definizioni delle viste indicizzate quando ne viene eseguita la manutenzione oppure quando vengono eseguite query in cui sono utilizzate viste indicizzate. Sebbene l'utilizzo di hint nelle definizioni delle viste indicizzate non comporti la generazione di un errore di sintassi nella modalità di compatibilità 80, gli hint vengono ignorati.