Domanda

Ho un indice sulle colonne A, B, C, D della tabella T

Ho una query che estrae da T con A, B, C nella clausola WHERE.

Verrà utilizzato l'indice o sarà necessario un indice separato che includa solo A, B, C?

È stato utile?

Soluzione

David B ha ragione sul fatto che dovresti controllare il piano di esecuzione per verificare che l'indice sia in uso.

Verrà utilizzato l'indice o sarà necessario un indice separato che includa solo A, B, C?

Per rispondere a quest'ultima parte della domanda, che ritengo sia l'argomento di base (al contrario della soluzione immediata), quasi non c'è mai motivo di indicizzare un sottoinsieme delle colonne indicizzate . Se il tuo indice è (A, B, C, D), un WHERE contro (A, B, C) molto probabilmente si tradurrà in un indice cerca , che è la situazione ideale - l'indice include tutte le informazioni necessarie al motore per andare direttamente al set di risultati. Credo che ciò sia vero per i tipi numerici e per i test di uguaglianza nei tipi di stringa, sebbene possa essere scomposto con LIKE '%' s). D'altra parte, se WHERE fa solo riferimento a D, molto probabilmente finiresti con un indice scan , il che significherebbe che il motore SQL dovrebbe eseguire la scansione di tutte le combinazioni di A, B e C, quindi controlla se D ha soddisfatto i tuoi criteri prima di decidere se aggiungere la riga al set di risultati. Su un tavolo particolarmente grande, quando mi sono ritrovato a dover fare molte domande sulla colonna "D", ho aggiunto un indice aggiuntivo solo per D e ho visto un miglioramento delle prestazioni di circa il 90%.

Modifica: dovrei anche raccomandare di utilizzare il sintonizzatore del motore di database in SQL Management Studio. Ti dirà se la tua tabella non è indicizzata idealmente per la query che desideri eseguire.

Altri suggerimenti

Dipende!

WHERE A like '%x%'
  and B = 1
  and C = 1
//
WHERE A = 1
  OR B = 1
  OR C = 1
//
WHERE DateAdd(dd, 1, A) = '2008-01-01'
  AND B = 1
  AND C = 1

Questi non si baseranno sull'indice, perché l'indice non è utile.

Fai clic su " visualizza il piano di esecuzione stimato " per confermare il potenziale utilizzo dell'indice.

nei database Oracle questo è chiamato Indice composito (Documenti 12g ma validi per le versioni precedenti)

  

Gli indici compositi possono accelerare il recupero dei dati per le istruzioni SELECT in cui la clausola WHERE fa riferimento a tutta la parte iniziale delle colonne nell'indice composito. Pertanto, l'ordine delle colonne utilizzate nella definizione è importante. In generale, le colonne a cui si accede più comunemente vanno per prime.

quindi nel tuo caso, Sì. l'indice sarebbe / potrebbe essere utilizzato. questo potrebbe essere verificato usando un piano esplicativo.

se MS SQLSERVER è diverso (e sospetto che potrebbe) avrai bisogno di una nuova risposta.

Modifica Dovresti anche menzionare che prenderà in considerazione l'indice per l'uso .. ciò non significa necessariamente che lo utilizzerà.

Edit2: Oracle 11g e versioni successive ora hanno un'opzione che gli permetterà di saltare le colonne in un indice. quindi una query su A, B e D potrebbe ancora utilizzare l'indice

Verrà utilizzato l'indice, sì. È abbastanza intelligente su quali indici produrranno un piano di query più ottimale e non dovrebbe avere problemi con questo.

Come in questo genere di cose, non credetemi, paragonatelo. Crea una tabella, riempila con dati rappresentativi, esegui una query, indicizzala e interrogala di nuovo.

Il fatto che l'indice contenga una colonna non utilizzata nella query non ne impedirà l'utilizzo.

Questo non vuol dire che verrà sicuramente utilizzato , potrebbe essere ignorato per un motivo diverso (forse perché uno o più altri indici sono più utili).

Come sempre, fai uno squizz al piano di esecuzione stimato per vedere cosa è probabile che accada.

Inizia con la ricerca semplice uguale (DOVE A = 1 e B = 'Rosso' e C = 287) sì, verrà probabilmente utilizzato l'indice. L'indice verrà utilizzato per primo per aiutare l'ottimizzatore "indovinare" il numero di righe che corrisponderanno alla selezione, quindi secondo, per accedere effettivamente a tali righe.

In risposta al commento di David B sul "mi piace" predicato, SQLServer può ancora utilizzare l'indice, dipende da ciò che si sta selezionando. Ad esempio, se si seleziona un conteggio (*), è probabile che SQL Server esegua la scansione dell'indice e conteggi gli hit che corrispondono alla clausola where poiché l'indice è più piccolo e richiederebbe meno IO per la scansione. E potrebbe decidere di farlo anche se si selezionano alcune colonne dalla tabella di base, a seconda di quanto SQLServer sia selettivo per l'indice.

Ecco un altro " dipende " risposta ... dipende anche da quanto è grande la tua tabella ...

Sono d'accordo con tutti gli altri che hanno menzionato la verifica del piano di esecuzione per verificare se l'indice viene utilizzato o meno.

Ecco un paio di articoli sulla lettura di un piano di esecuzione che dovresti trovare utili:

http://www.sqlservercentral.com/articles/Administers/executionplans/ 1345 / http://www.codeproject.com/KB/database/ sql-tuning dimostrativi-1.aspx

C'è anche un buon articolo su ricerche e scansioni che consiglierei: http://blogs.msdn.com/craigfr/archive/ 2006/06/26 / 647852.aspx

Sul blog di Craig Freedman c'è un registro di buoni articoli, eccone un altro che dovresti trovare utile. Questo articolo riguarda alcuni dei fattori utilizzati da SQL Server per determinare quale indice utilizzare ...

http://blogs.msdn.com/craigfr /archive/2006/07/13/664902.aspx

Abbi cura di te! Jeff

In generale sì, tutti i database moderni sono abbastanza intelligenti da farlo. Ci sono eccezioni, ad esempio, se le statistiche sulla tabella mostrano che il volume di dati in esso è sufficientemente piccolo da rendere più efficiente una lettura della tabella completa, allora l'indice sarà scontato, ma di norma puoi fare affidamento su di esso se del caso.

Di conseguenza, puoi trarne vantaggio durante la progettazione degli indici. Supponiamo ad esempio che ho una tabella che contiene A, B, C come valori chiave e colonne Y e Z contenenti dati che so che verranno recuperati spesso dalle istruzioni

SELECT Y FROM table WHERE A = alpha and B = beta and C = gamma 

SELECT Z FROM table WHERE A = alpha and B = beta and C = gamma 

L'I generalmente creerà un indice su A, B, C, X, Z - supponendo che X e Z siano un campo ragionevolmente piccolo. La ragione di ciò è che so che il percorso di accesso nelle istruzioni sopra utilizzerà l'indice e poiché i dati che voglio recuperare sono già nell'indice letti , quindi nessuna lettura separata del blocco di dati sarà necessario per recuperare i dati della tabella stessa. Questa strategia può velocizzare notevolmente il recupero dei dati in alcune circostanze. Ovviamente, lo paghi in termini di costi di aggiornamento e spazio su disco, quindi devi capire cosa sta facendo il tuo database prima di applicarlo, ma come nella maggior parte dei database legge drammaticamente in numero maggiore rispetto alle scritture, generalmente vale la pena prendere in considerazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top