2009-04-28 13 views
181

Per definizione (almeno da quello che ho visto) sargable significa che una query è in grado di fare in modo che il motore di query ottimizzi il piano di esecuzione utilizzato dalla query. Ho provato a cercare le risposte, ma non sembra esserci molto sull'argomento. Quindi la domanda è, che cosa fa o non rende una query SQL sargable? Qualsiasi documentazione sarebbe molto apprezzata.Che cosa rende sargable un'istruzione SQL?

Per riferimento: Sargable

+41

+1 per "sargable". Questa è la mia parola del giorno per oggi. :-p – BFree

+25

SARG = Cerca ARGument. La cosa divertente è: "SARG" in tedesco significa "bara", quindi devo sempre sorridere quando la gente parla di SARGABLE - capace di essere messo in una bara? :-) –

+0

sargability dipende dal tuo ambiente. MySQL è documentato qui: http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html –

risposta

178

La cosa più comune che farà una query non sargable è quello di includere un campo all'interno di una funzionenella clausola WHERE:

SELECT ... FROM ... 
WHERE Year(myDate) = 2008 

L'ottimizzatore SQL non può utilizzare un indice su myDate, anche se ne esiste uno. Dovrà letteralmente valutare questa funzione per ogni riga del tavolo. Molto meglio usare:

WHERE myDate >= '01-01-2008' AND myDate < '01-01-2009' 

Alcuni altri esempi:

Bad: Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones' 
Fixed: Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL)) 

Bad: Select ... WHERE SUBSTRING(DealerName,4) = 'Ford' 
Fixed: Select ... WHERE DealerName Like 'Ford%' 

Bad: Select ... WHERE DateDiff(mm,OrderDate,GetDate()) >= 30 
Fixed: Select ... WHERE OrderDate < DateAdd(mm,-30,GetDate()) 
+6

Includendo una funzione all'interno di 'GROUP BY', una query diventa non-sargabile? –

+0

@MikeBantegui Il solo inserimento di un campo in un GROUP BY non lo renderà necessariamente non condivisibile, no. Gli indici corretti aiuteranno sicuramente una query GROUP BY. – BradC

+1

* Alcuni motori di database * (Oracle, PostgreSQL) supportano gli indici sulle espressioni, non lo so? – Craig

62

non farlo:

WHERE Field LIKE '%blah%' 

che provoca una scansione di tabella/indice, in quanto il valore COME inizia con un carattere jolly.

Non fare questo:

WHERE FUNCTION(Field) = 'BLAH' 

che provoca una scansione di tabella/index.

Il server di database dovrà valutare FUNCTION() su ogni riga della tabella e quindi confrontarlo con "BLAH".

Se possibile, lo fanno in senso inverso:

WHERE Field = INVERSE_FUNCTION('BLAH') 

Questo verrà eseguito INVERSE_FUNCTION() con il parametro di una volta e sarà ancora consentire l'uso dell'indice.

+3

Il tuo suggerimento con la funzione di capovolgimento funzionerà davvero solo quando la funzione esegue il round-trip dei dati (ovvero f (f (n)) = n). –

+4

Vero. Ho preso in considerazione l'aggiunta di INVERSE_FUNCTION ma non volevo essere confuso. Lo cambierò. – beach

7

In questa risposta ho assumere il database ha sufficienti indici che coprono. Ci sono abbastanza domande su this topic.

Molte volte la sargibilità di una query è determinata dal punto di non ritorno degli indici correlati. Il punto di non ritorno definisce la differenza tra la ricerca e la scansione di un indice mentre si aggiunge una tabella o un set di risultati a un altro. Ovviamente, una ricerca è molto più veloce della scansione di un intero tavolo, ma quando si devono cercare molte righe, una scansione potrebbe avere più senso.

Quindi, tra le altre cose, un'istruzione SQL è più sargevole quando l'ottimizzatore si aspetta che il numero di righe risultanti di una tabella sia inferiore al punto di non ritorno di un possibile indice sulla tabella successiva.

È possibile trovare un post dettagliato ed un esempio here.

0

Per un'operazione da considerare sargable, non è sufficiente che sia in grado di utilizzare un indice esistente.Nell'esempio sopra riportato, l'aggiunta di una chiamata di funzione a una colonna indicizzata nella clausola where, potrebbe molto probabilmente avvantaggiarsi dell'indice definito. "Scansionerà", ovvero recupererà tutti i valori da quella colonna (indice) e quindi eliminerà quelli che non corrispondono al valore del filtro fornito. Non è ancora abbastanza efficiente per le tabelle con un numero elevato di righe. Ciò che veramente definisce sargability è la capacità di query di attraversare l'indice b-tree utilizzando il metodo di ricerca binaria che si basa sull'eliminazione di metà set per l'array di elementi ordinati. In SQL, sarebbe visualizzato nel piano di esecuzione come "ricerca indice".

Problemi correlati