2010-05-27 5 views
6

Questa domanda riguarda ciò che accade con la riorganizzazione dei dati in un indice cluster quando viene eseguito un inserimento. Suppongo che dovrebbe essere più costoso fare inserti su una tabella che ha un indice cluster rispetto a uno che non lo è perché la riorganizzazione dei dati in un indice cluster comporta la modifica del layout fisico dei dati sul disco. Non sono sicuro di come esprimere la mia domanda se non attraverso un esempio che mi sono imbattuto nel lavoro.Indice cluster - multiparte vs indice di parte singola ed effetti di inserimenti/eliminazioni

Supponiamo che ci sia una tabella (Junk) e che ci siano due query sulla tabella, la prima query cerca per Nome e la seconda query cerca per Nome e Qualcosa. Come sto lavorando sul database ho scoperto che la tabella è stata creata con due indici, uno per sostenere ogni query, in questo modo:

--drop table Junk1 
CREATE TABLE Junk1 
(
    Name char(5), 
    Something char(5), 
    WhoCares int 
) 

CREATE CLUSTERED INDEX IX_Name ON Junk1 
(
    Name 
) 

CREATE NONCLUSTERED INDEX IX_Name_Something ON Junk1 
(
    Name, Something 
) 

Ora, quando ho guardato i due indici, sembra che IX_Name è ridondante poiché IX_Name_Something può essere utilizzato da qualsiasi query che desideri cercare per Nome. Quindi vorrei eliminare IX_Name e rendere IX_Name_Something l'indice cluster invece:

--drop table Junk2 
CREATE TABLE Junk2 
(
    Name char(5), 
    Something char(5), 
    WhoCares int 
) 

CREATE CLUSTERED INDEX IX_Name_Something ON Junk2 
(
    Name, Something 
) 

Qualcuno ha suggerito che il primo schema di indicizzazione dovrebbe essere mantenuto in quanto porterebbe ad inserti più efficienti/cancella (si presuppone che non c'è bisogno di preoccuparsi aggiornamenti per Nome e Qualcosa). Avrebbe senso? Penso che il secondo metodo di indicizzazione sarebbe migliore poiché significa che è necessario mantenere un indice in meno.

Gradirei qualsiasi informazione su questo specifico esempio o indirizzarmi a maggiori informazioni sulla manutenzione degli indici cluster.

risposta

9

Sì, l'inserimento nel centro di una tabella esistente (o della sua pagina) potrebbe essere costoso quando si dispone di un indice cluster non ottimale. Il caso peggiore sarebbe una divisione della pagina: metà delle righe sulla pagina dovrebbero essere spostate altrove e gli indici (compresi gli indici non in cluster su quella tabella) devono essere aggiornati.

È possibile alleviare il problema utilizzando il giusto indice cluster - uno che gode di un'ottima:

  • stretto (solo un singolo campo, il più piccolo possibile)
  • statica (non cambia mai)
  • unico (in modo che SQL Server non ha bisogno di aggiungere uniqueifiers 4 byte per le righe)
  • sempre crescenti (come un INT IDENTITY)

Si desidera una chiave stretta (idealmente un singolo INT) poiché ogni singola voce in ogni singolo indice non in cluster conterrà anche le chiavi di clustering: non si desidera inserire molte colonne nella chiave di clustering, né vuoi mettere cose come VARCHAR (200) lì!

Con un indice cluster sempre crescente, non si vedrà mai il caso di una pagina divisa. L'unica frammentazione che potresti incontrare è da eliminare (problema "formaggio svizzero").

Scopri tutti i messaggi di Kimberly Tripp excellet blog su indicizzazione - in particolare:

supponga c'è un tavolo (Junk) e ci sono due query che sono state svolte sul tavolo, le prime ricerche di query di nome e il secondo ricerche di query di Nome e Qualcosa. Come io sto lavorando database ho scoperto che il tavolo è stato creato con due indici, uno per sostenere ogni query, in questo modo:

Questo non è assolutamente necessario - se si dispone di un indice su (Name, Something), tale indice può anche essere utilizzato anche se si cerca e si limita solo a WHERE Name = abc - avere un indice separato con solo la colonna Name non è assolutamente necessario e solo spreca spazio (e costa tempo per essere aggiornato).

Quindi, in pratica, è necessario un solo indice su (Name, Something) e sarei d'accordo con te: se non ci sono altri indici su questa tabella, dovresti essere in grado di renderlo la chiave in cluster. Dal momento che quella chiave non sarà mai in aumento e potrebbe anche cambiare (giusto?), Questa potrebbe non essere una grande idea.

L'altra opzione sarebbe quella di introdurre un surrogato ID INT IDENTITY e cluster su che - con due vantaggi:

  • è tutto una buona chiave cluster dovrebbe essere, tra cui sempre crescente -> non dovrete mai qualsiasi problemi con divisioni di pagina e le prestazioni per le operazioni INSERISCI
  • è ancora ottenere tutti i vantaggi di avere una chiave di clustering (vedi Kim Tripps' post del blog - tabelle cluster sono quasi sempre preferibile a cumuli)
+1

Bella spiegazione completa. –

0

Qualcuno ha suggerito che il primo schema di indicizzazione dovrebbe essere mantenuto in quanto porterebbe ad inserti più efficienti/cancella

Questa è un'affermazione falsa. I dati ordinati sono dati ordinati e verrà eseguito lo stesso IO.

SET STATISTICS IO ON 
-- your insert statement here 
0

È possibile creare un indice cluster solo su una colonna, non due o più in modo da scegliere la colonna che la vostra applicazione sarà in gran parte essere eseguendo una ricerca, come le query jolly su fullnames dei clienti, ecc (vedi discussion)

+0

Che è falso, leggere: http://msdn.microsoft.com/en-us/library/aa933131(SQL.80).aspx "una tabella può contenere solo un indice cluster. Tuttavia, l'indice può comprendere più colonne " – Anssssss