Domanda

Supponiamo che io bisogno di aggiornare mytab da luTab come segue

update myTab
  set LookupVale = (select LookupValue from luTab B
                                       where B.idLookup = myTab.idLookup)

luTab costituito da 2 colonne (idLookup (unico), LookupValue)

che è preferibile: un indice univoco cluster in idLookup, o uno su idLookup e Lookupvalue combinati? È un indice di copertura andando a fare alcuna differenza in questa situazione?

(sono per lo più interessati in SQL Server)


Epilogo:

Ho seguito Krips test indicati con righe 27M in mytab, 1,5 M righe luTab. La parte cruciale sembra essere l'unicità dell'indice. Se l'indice è specificato come unico, l'aggiornamento usa una tabella di hash. Se non è specificato come unico, quindi il primo aggiornamento aggreates luTab dal idLookup (l'Aggegate Stream) e quindi utilizza un ciclo annidato. Questo è molto più lento. Quando uso l'indice esteso, SQL ora non è più assued che quel LookupValue è unico per cui il suo forzata lungo il molto più lento, flusso aggregato-nidificato percorso ad anello

È stato utile?

Soluzione

Ho creato le tabelle e caricato a pochi record (50 o giù di lì di ricerca, e 15 in mytab).

Poi ho provato varie opzioni su indici. L'indice Seek su luTab ha sempre un costo di 29%.

La cosa interessante è che se si aggiunge nella colonna LookupValue all'indice sulla luTab il piano di esecuzione mostra due passaggi aggiuntivi dopo l'indice Seek: Flusso Aggregate e affermare. Mentre il costo è pari a 0%, che può salire con altri dati.

Ho provato anche un indice non cluster su un solo idLookup, e comprendente LookupValue come 'colonna Incluso'. In questo modo le pagine di dati non hanno bisogno di accedere per recuperare che quella colonna. Che può essere un'opzione per voi, anche se il piano di esecuzione non mostra nulla di diverso (ma non hanno il flusso aggregato / Assert o).

-Krip

Altri suggerimenti

In primo luogo:

  • Un indice di copertura è sempre non cluster
  • Si dovrebbe sempre avere un PK e un indice cluster (ci sono gli stessi di default su SQL Server)

I 2 concetti sono separati

  • Il tuo PK (cluster) sarebbe idLookup se questo identifica in modo univoco una riga
  • L'indice di copertura sarebbe (idLookup) INCLUDE (LookupValue)

Tuttavia:

  • idLookup è la PK (cluster), quindi non è necessario un indice di copertura
  • l'indice cluster (PK) è implicitamente "copertura" per la natura di un indice cluster (semplicemente, i dati indice è al livello più basso)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top