2009-04-27 17 views
49

Ho creato indici compositi (indici per voi gente di matematica) sui tavoli prima con un'ipotesi di come funzionavano. Ero solo curioso di sapere se la mia ipotesi fosse corretta o meno.Come funzionano gli indici compositi?

Presumo che quando si elenca l'ordine delle colonne per l'indice, si specifica anche come verranno raggruppati gli indici. Ad esempio, se si dispone di colonne a, b e c e si specifica l'indice nello stesso ordine a ASC, b ASC, e c ASC allora l'indice risultante sarà essenzialmente molti indici per ogni "gruppo" in a.

È corretto? In caso contrario, quale sarà l'indice risultante?

+0

vedere qui: [SQL Server copre indici] (http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/sql-server-covering-indexes) per una buona spiegazione – SQLMenace

+0

Questo mi sembra un composito index to me CREATE INDICE NONCLUSTERED idx_PeopleTest_Name_Id_FavoriteColor ON PeopleTest (Name, Id, FavoriteColor) – SQLMenace

risposta

54

Gli indici compositi funzionano proprio come gli indici normali, eccetto che hanno chiavi multi-valore.

Se si definisce un indice sui campi (a, b, c), i record vengono ordinati prima su a, quindi su b, quindi su c.

Esempio:

| A | B | C | 
------------- 
| 1 | 2 | 3 | 
| 1 | 4 | 2 | 
| 1 | 4 | 4 | 
| 2 | 3 | 5 | 
| 2 | 4 | 4 | 
| 2 | 4 | 5 | 
+7

Si noti inoltre che gli indici sono memorizzati come Btree, quindi un indice (a, b, c) aiuterà su una ricerca su (a) e su (a, b), ma * non * su altre ricerche come (b) o (avanti Cristo). – aexl

3

No. L'indice risultante sarà un indice singolo ma con chiave composta.

KeyX = A, B, C, D; KeyY = 1,2,3,4;

Indice KeyX, KeyY sarà realtà: A1, A2, A3, B1, B3, C3, C4, D2

In modo che in caso di necessità di trovare qualcosa da KeyX e KeyY - che sarà veloce e userà l'indice singolo. Qualcosa come SELECT ... WHERE KeyX = "B" AND KeyY = 3.

Ma è importante capire: WHERE KeyX =? richieste saranno utilizzare quell'indice, mentre WHERE KeyY =? sarà NON utilizzare tale indice a tutti.

+0

L'ultima affermazione non è vera su Oracle. Vedi http://stackoverflow.com/questions/57878/sql-oracle-when-indexes-on-multiple-columns-can-be-used (ignora la risposta - errata - accettata). – Hobo

+0

@Hobo: 1. Nella maggior parte dei RDBMS, skip scan non è disponibile. 2. Nella maggior parte dei casi sarebbe MOLTO lento, solo un po 'più veloce (e talvolta anche più lento) rispetto alla semplice scansione della tabella (in situazioni molto rare sarà davvero d'aiuto). Nessuna magia in Oracle. Solo una buona regola da ricordare: NON fare affidamento sull'indice composto se i criteri non utilizzano solo le colonne di livello superiore dall'indice (è un errore molto comune creare indici composti di grandi dimensioni). – Mash

+0

Punti @Mash presi.Sicuramente non dico che skip scan sono una pallottola d'argento, solo che ci sono circostanze in cui KeyY =? _will_ usa un indice. Immagino sia meglio dare un'immagine più completa possibile. Per quanto riguarda la velocità, spero che l'ottimizzatore scelga l'approccio appropriato (anche se, come sempre, misurerebbe piuttosto che assumere in caso di dubbio) – Hobo

17

L'implementazione più comune di indici utilizza alberi B per consentire ricerche piuttosto rapidi, e anche scansioni gamma ragionevolmente rapidi. È troppo da spiegare qui, ma ecco l'articolo di Wikipedia su B-trees. E hai ragione, la prima colonna dichiarata nell'indice di creazione sarà la colonna di ordine superiore nell'albero B risultante.

Una ricerca nella colonna di ordine superiore equivale a una scansione di intervallo e un indice di albero B può essere molto utile per tale ricerca. Il modo più semplice per vederlo è per analogia con i vecchi cataloghi di schede che hai nelle librerie che non sono ancora stati convertiti in cataloghi on line.

Se state cercando tutte le carte per autori il cui cognome è "Clemens", andate semplicemente al catalogo dell'autore e trovate molto rapidamente un cassetto che dice "CLE-CLI" sul davanti. Quello è il cassetto giusto Ora fai una specie di ricerca binaria informale in quel cassetto per trovare rapidamente tutte le carte che dicono "Clemens, Roger" o "Clemens, Samuel" su di loro.

Ma supponiamo di voler trovare tutte le carte per gli autori il cui nome è "Samuel". Ora sei su per il torrente, perché quelle carte non sono riunite in un posto nel catalogo degli autori. Un fenomeno simile si verifica con gli indici compositi in un database.

I diversi DBMS si differenziano per quanto intelligente sia il loro ottimizzatore nel rilevamento delle scansioni del range dell'indice e per la stima accurata del loro costo. E non tutti gli indici sono alberi B. Dovrai leggere i documenti per il tuo DBMS specifico per ottenere le informazioni reali.

+0

grazie, ho pensato a questo problema con difficoltà, senza una risposta chiara. "Una ricerca nella colonna ordine elevato equivale a una scansione intervallo", ma cosa succede se l'indice copre 2 colonne e entrambe le colonne sono specificate in una query di intervallo, ad esempio "ColonnaA soglia 2 E colonnaB threshold4 ", sembra che oracle debba spendere scansioni dell'intervallo MULTIPLE sull'albero B, giusto? quindi nel caso in cui abbiamo molte colonne nell'indice composito, dobbiamo fare MOLTE scansioni dell'intervallo, e l'efficacia dell'indice si riduce notevolmente –

+0

Nella mia risposta, intendevo che ColumnA = valore ammonta a una scansione di intervallo, perché potrebbero esserci molti voci che hanno tutti il ​​giusto valore per ColumnA ma diversi valori per ColumnB. Il tuo caso è molto diverso. Potrebbe ancora essere una scansione di intervallo, ma l'intervallo potrebbe coinvolgere una grande percentuale delle voci nell'indice. Più grande è il raggio, meno l'indice ti salva. Se il valore di utilizzo dell'indice scende troppo basso, l'ottimizzatore potrebbe optare per una strategia diversa. –

28

indice composito è come un indice alfabeto normale in un dizionario, ma copre due o più lettere, in questo modo:

AA - page 1 
AB - page 12 

ecc

righe della tabella sono ordinate prima per la prima colonna della indice, poi dal secondo ecc.

È utilizzabile quando si esegue la ricerca in entrambe le colonne O per prima colonna. Se l'indice è come questo:

AA - page 1 
AB - page 12 
… 
AZ - page 245 
BA - page 246 
… 

si può utilizzare per la ricerca sul 2 lettere (= 2 colonne di una tabella), o come un indice di pianura su una lettera:

A - page 1 
B - page 246 
… 

Si noti che in caso di un dizionario, le pagine stesse sono ordinate alfabeticamente. Questo è un esempio di indice CLUSTERED.

In una pianura, non CLUSTERED indice, i riferimenti alle pagine sono ordinate, come in un libro di storia:

Gaul, Alesia: pages 12, 56, 78 
Gaul, Augustodonum Aeduorum: page 145 
… 
Gaul, Vellaunodunum: page 24 
Egypt, Alexandria: pages 56, 194, 213, 234, 267 

indici compositi possono anche essere utilizzati quando si ORDER BY due o più colonne. In questo caso potrebbe essere utile una clausola DESC.

Vedere questo articolo nel mio blog sull'utilizzo DESC clausola di un indice composto:

0

mia comprensione è, indici compositi lavorare proprio come indici regolari, tranne hanno valori multipli chiavi. Se si definisce un indice sui campi (a, b, c), poiché l'indice composito verrà memorizzato in un BinaryTree, l'indice funzionerà solo in seguito a combinazioni di ricerche.

ABC 
AB 
A 

Ad esempio creando un indice composito di a, b, c campo equivale a creare indici separati per una, ab e abc.