Perché le viste indicizzate non consentono indici cluster non univoci?


12

Ho esaminato l'utilizzo delle viste indicizzate per aumentare le prestazioni su alcune delle nostre viste più comunemente utilizzate.

Tuttavia, le viste indicizzate non supportano indici cluster non univoci che vanno leggermente contro la precedenza impostata dal resto della struttura del database.

Ad esempio, ecco una versione semplificata di un paio dei nostri tavoli.

-Groups-
Group ID    GroupName

-Users-
UserKey    UserName    FullName     GroupID

Gli indici si trovano su Groups.GroupID (Non cluster) e Users.GroupID (Clustered). La chiave cluster che si trova su GroupID nella tabella Users come più comunemente viene recuperato un intervallo di utenti da un gruppo specifico. Ovviamente avresti più utenti per gruppo, quindi questo indice cluster non è univoco.

Questo mi lascia un po 'incerto su come seguire questa precedenza quando indicizzo le mie opinioni come questo esempio, poiché non posso avere un indice cluster non univoco.

ConsumableID    ConsumableVariantID AllowThresholdOverwrite FullPath    GroupID ManufacturerID  Type    ModelID
101              29                 1                       0.1.2.4.    4       3               3       2

In realtà, l'unico valore su questa vista che sarebbe sempre unico è la colonna ConsumableID, quindi mi rimane poca scelta su dove posizionare il mio indice.

Perché le visualizzazioni non consentono indici cluster non univoci quando le tabelle normali lo fanno?


3
C'è una breve spiegazione nella parte inferiore di questa pagina intitolata "Perché il primo indice di una vista deve essere CLUSTER e UNICO?" ma non fa molti dettagli. Sarei sicuramente interessato a sentire una spiegazione più dettagliata.
Steve Pettifer,

5
Un paio di commenti: 1 - Non c'è motivo per cui non sia possibile raggrupparsi (GroupID, UserID). Non limitarti a una singola colonna per la chiave. 2 - Immagino che il limite per una vista sia perché si tratta di un oggetto dati supplementare che deve avere righe facilmente legate agli indici NC. Per una tabella, la chiave CI non univoca viene aggiunta a un int, ma penso che sarebbe più impegnativo con una vista indicizzata poiché non è una tabella reale ma deve RIFLETRE una tabella effettiva.
JNK

Risposte:


22

La seguente spiegazione viene fornita in questo articolo tecnico Microsoft :

Perché il primo indice in una vista deve essere CLUSTER e UNICO?

Deve essere UNICO per consentire una facile ricerca dei record nella vista in base al valore chiave durante la manutenzione della vista indicizzata e per impedire la creazione di viste con duplicati, che richiederebbero una logica speciale da mantenere. Deve essere raggruppato perché solo un indice cluster può imporre l'univocità e memorizzare le righe contemporaneamente.

SQL Server utilizza un sistema di algebra delta per mantenere le visualizzazioni indicizzate al passo con i dati di base. Incorpora inoltre automaticamente gli operatori del piano di query di manutenzione della vista per ogni query DML che influisce su una o più viste indicizzate. Avere un indice cluster univoco nella vista semplifica notevolmente i dettagli di implementazione.

La disposizione attuale consente di incorporare le forme dell'albero degli operatori di manutenzione a forma fissa nell'albero delle query DML di base, fornendo ortogonalità che semplifica anche i test. In definitiva, le visualizzazioni indicizzate potrebbero essere migliorate un giorno per supportare indici cluster non univoci, ma poi tutte le cose sono possibili con tempo illimitato e risorse illimitate (nessuna delle quali si applica al team di sviluppo di SQL Server al momento della stesura).

Per un esempio che mostra la complessità della costruzione del piano di query di aggiornamento e la facilità con cui possono insinuarsi bug sottili, vedere questo esempio di un bug che si verifica con MERGEe indici filtrati (una funzionalità che ha una stretta connessione con le viste indicizzate).


2
Un errore simile può verificarsi se si tenta di aggiornare una vista indicizzata con una GROUP BYclausola ma non tutte le espressioni di raggruppamento sono chiavi nell'indice cluster. È valido a partire da SQL Server 2014.
Quassnoi,

4

In SQL Server tutte le chiavi di indice devono essere univoche internamente. Ciò è necessario per ottenere chiavi di blocco che si indirizzano esattamente a una riga. È inoltre richiesto per la manutenzione dell'indice. Immagina un NCI su una colonna che contiene solo un valore (duplicati al 100%). Se una riga viene eliminata dalla tabella, il motore di archiviazione deve trovare la riga NCI corrispondente ed eliminarla. Se tutte le file NCI sono indistinguibili, ciò sarebbe impossibile.

Quindi vedi che l'elemento della configurazione in una vista deve essere (internamente) univoco affinché il motore funzioni.

Se non rendi un indice univoco, SQL Server lo rende comunque unico internamente. Nel caso di un NCI su una tabella heap, aggiunge il segnalibro di riga. Nel caso di un elemento della configurazione non univoco, aggiunge una colonna uniquifier. Nel caso di un NCI su una tabella con un elemento della configurazione, viene aggiunta qualsiasi colonna chiave dell'elemento della configurazione che non è stata già specificata dall'utente (questo potrebbe includere l'unicificatore).

Non esiste una colonna ovvia che potrebbe essere aggiunta in caso di una vista indicizzata. Quindi SQL Server non può farlo automaticamente.

Normalmente, per un essere umano è abbastanza ovvio quali colonne è possibile aggiungere per rendere la vista un set univoco di colonne da utilizzare nell'elemento della configurazione. Queste sono normalmente le colonne PK o CI di una delle tabelle sottostanti. Se la vista ha GROUP BYnormalmente un indice sulle chiavi di raggruppamento.


2
Consiglio vivamente di rivedere la formulazione di questa risposta. Sebbene contenga un punto valido per quanto riguarda la domanda originale, potrebbe sembrare che suggerisca che tutti gli indici non univoci contengano unificatori, ma non è così.
spaghettidba,

@spaghettidba grazie, non me ne sono accorto. Spero sia meglio adesso.
usr

Scusa, non ancora. Stai mescolando due cose insieme. Gli indici non cluster non devono essere univoci e non unificati internamente: non stai chiarendo abbastanza questo punto. Tutto ciò che dici nella tua risposta si applica solo agli indici cluster.
spaghettidba,

Gli NCI @spaghettidba sono sempre unici internamente. Possono sempre generare tutte le chiavi CI come parte di un piano di query. Vedi pastebin.com/vkGHpCsR La pagina di dati NCI contiene entrambe le colonne.
usr

Vedo da dove vieni. Più leaf possono condividere la stessa chiave di indice, ma la chiave di clustering è sempre inclusa negli NCI. Basta dire che sono sempre unici internamente? Io non la penso così.
spaghettidba,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.