2009-04-28 7 views
181

Per Definition (zumindest von dem, was ich gesehen habe) Sargable bedeutet, dass eine Abfrage in der Lage ist, die Abfrage-Engine den Ausführungsplan, den die Abfrage verwendet, zu optimieren. Ich habe versucht, die Antworten nachzuschlagen, aber zum Thema scheint es nicht viel zu geben. Die Frage ist also, was eine SQL-Abfrage sargierbar macht oder nicht? Jede Dokumentation würde sehr geschätzt werden.Was macht eine SQL-Anweisung als Sargable?

Zum Vergleich: Sargable

+41

+1 für "Sargable". Das ist mein Tageswort für heute. :-p – BFree

+25

SARG = Suche ARGument. Witzig ist: "SARG" heißt auf Deutsch "Sarg", also muss ich immer lächeln, wenn Leute über SARGABLE sprechen - in einen Sarg gesteckt werden können? :-) –

+0

Sargability hängt von Ihrer Umgebung ab. MySQL ist hier dokumentiert: http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html –

Antwort

178

Die häufigste Sache, die eine Abfrage nicht sargable macht ist ein Feld in einer Funktion in der where-Klausel enthalten:

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

Die SQL-Optimierer einen Index verwenden können auf myDate, auch wenn es einen gibt. Es muss diese Funktion buchstäblich für jede Zeile der Tabelle auswerten. Viel besser zu nutzen:

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

Einige weitere Beispiele:

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

Wird eine Funktion innerhalb von GROUP BY dazu führen, dass eine Abfrage nicht sargierbar wird? –

+0

@MikeBantegui Wenn Sie nur ein Feld in eine GROUP BY einfügen, wird dies nicht unbedingt sargeable, nein. Die richtigen Indizes werden definitiv einer GROUP BY-Abfrage helfen. – BradC

+1

* Einige * Datenbank-Engines (Oracle, PostgreSQL) unterstützen Indizes auf Ausdrücke, dontcha wissen? – Craig

62

Tun Sie dies nicht tun:

WHERE Field LIKE '%blah%' 

, die eine Tabelle/Index-Scan verursacht, weil der LIKE-Wert mit einem Platzhalter-Zeichen beginnt.

Tun Sie dies nicht tun:

WHERE FUNCTION(Field) = 'BLAH' 

, die eine Tabelle/Index-Scan verursacht.

Der Datenbankserver muss FUNCTION() für jede Zeile in der Tabelle auswerten und dann mit 'BLAH' vergleichen. Wenn möglich

, tun Sie es in umgekehrter Richtung:

WHERE Field = INVERSE_FUNCTION('BLAH') 

Dies läuft INVERSE_FUNCTION() gegen die Parameter einmal und wird nach wie vor Verwendung des Index ermöglichen.

+3

Ihr Vorschlag mit dem Umdrehen der Funktion würde nur funktionieren, wenn die Funktion Daten umkehrt (dh dass f (f (n)) = n). –

+4

Wahr. Ich überlegte, INVERSE_FUNCTION hinzuzufügen, wollte aber nicht verwirren. Ich werde es ändern. – beach

7

In dieser Antwort gehe ich davon aus der Datenbank ausreichend abdeckt Indizes hat. Es gibt genug Fragen über this topic.

Oft wird die Sargability einer Abfrage durch den Wendepunkt der zugehörigen Indizes bestimmt. Der Wendepunkt definiert den Unterschied zwischen dem Suchen und Scannen eines Index beim Verbinden einer Tabelle oder eines Ergebnissatzes mit einem anderen. Eine Suche ist natürlich viel schneller als das Scannen einer ganzen Tabelle, aber wenn Sie viele Zeilen suchen müssen, könnte ein Scan sinnvoller sein.

So ist eine SQL-Anweisung unter anderem sargabler, wenn das Optimierungsprogramm erwartet, dass die Anzahl der resultierenden Zeilen einer Tabelle kleiner als der Kipppunkt eines möglichen Index für die nächste Tabelle ist.

Sie finden eine detaillierte Post und Beispiel here.

0

Damit eine Operation als sargable betrachtet werden kann, reicht es nicht aus, nur einen vorhandenen Index zu verwenden.Im obigen Beispiel würde das Hinzufügen eines Funktionsaufrufs für eine indizierte Spalte in der WHERE-Klausel immer noch einen gewissen Vorteil des definierten Index haben. Er "scannt" aka, ruft alle Werte aus dieser Spalte (Index) ab und entfernt dann diejenigen, die nicht mit dem angegebenen Filterwert übereinstimmen. Es ist immer noch nicht effizient genug für Tabellen mit einer hohen Anzahl von Zeilen. Was Sargability wirklich definiert, ist die Query-Fähigkeit, den B-Tree-Index mit der Binärsuchmethode zu durchlaufen, die für das Sorted-Items-Array auf die Eliminierung von Halbsätzen angewiesen ist. In SQL würde es im Ausführungsplan als "Indexsuche" angezeigt.