Sargable Abfragen

7

Sehr einfache Frage Ich hoffe, ich habe derzeit einige Skripte, die ich in mein Projekt geerbt habe, die von den Datenbankadministratoren überprüft wurden. Dies wurde anscheinend noch nie zuvor gemacht und es werden viele Probleme gefunden.

Ich bin ein bisschen neu in diesem Bereich, aber mein Verständnis von Sargable und Non-Sargable SQL ist, dass die fehlerhafte Funktion für die Spalte ausgeführt wird und somit den Index blockiert (vorausgesetzt, einer ist vorhanden), was zu einem Scan der Spalte und a führt Leistungseinbruch. Der Code hat mehrere Funktionen in der Eingabe, viele kleinere Dinge, wie

Where a.date between 'inputdate' and dateadd(day,1,'inputdate')

Der DBA hat die Auffassung vertreten, dass jede Abfrage, die eine Funktion in der WHEREKlausel enthält, nicht saragierbar ist. Ich werde das Problem mit ihm fallen lassen, weil mich das Streiten nirgendwohin bringt, außer einem verärgerten Administrator und meinem eingeschränkten Zugriff.

Aber gibt es aus Wissensgründen einen Fall, in dem er korrekt ist und jede in der WHEREKlausel enthaltene Funktion ein Problem darstellt, unabhängig von Funktion oder Platzierung?

sten
quelle
4
Nein, wenn die Abfrage das ist, was Sie zeigen, ist er völlig falsch. Es ist ziemlich sargable wie es ist. (Ich würde es nicht BETWEENmit Datumsangaben verwenden, aber das ist ein anderes, nicht verwandtes Problem.) Sie zeigen uns jedoch nur eine Abfrage. Wenn Sie Dutzende von Abfragen mit nicht sargierbaren Bedingungen und Funktionsaufrufen haben, haben sie möglicherweise die tatsächlich sargable verpasst.
Ypercubeᵀᴹ
1
Das ist wahrscheinlich der Fall, dass ich etwas im Code verpasst habe. Aber ich drängte auf Klärung des Problems der Sargabilität speziell zu meinem eigenen Vorteil und mir wurde gesagt, dass es für JEDE Funktion in der WHERE- oder ON-Klausel von Bedeutung sei. Das ergab für mich logischerweise keinen Sinn, da der Grund für das Problem in erster Linie darin bestand, die Verwendung von Indizes zuzulassen ... und Sie können keine einzelne Eingabe indizieren.
Sten
1
Verfügt SQL Server nicht über Funktionsindizes oder zumindest über berechnete Spalten mit Indizes?
Vérace
2
Übrigens bezieht sich der Begriff "sargable" normalerweise auf einzelne Prädikate, nicht auf Abfragen.
Mustaccio
1
@BrentOzar hat eine ziemlich leicht verständliche Sicht auf Sargability unter brentozar.com/archive/2010/06/sargable-why-string-is-slow
Max Vernon

Antworten:

7

Wie ypercube kommentierte

Nein, wenn die Abfrage das ist, was Sie zeigen, ist er völlig falsch. Es ist ziemlich sargable wie es ist.

Sie können dies überprüfen, indem Sie:

  • Erstellen einer einfachen Testtabelle mit einer Spalte [Datum].
  • Fügen Sie eine große Anzahl von Zeilen mit unterschiedlichen Daten ein.
  • HINWEIS: In den obigen Abschnitten ist "große Anzahl" und "unterschiedliche Daten" eine Vorsichtsmaßnahme, um sicherzustellen, dass Ihre Abfrage selektiv genug ist . Andernfalls kann der Optimierer entscheiden, Ihren Index in keinem Fall zu verwenden.
  • Generieren Sie einen Abfrageplan für Ihre Abfrage (einmal mit einem Index in der Spalte Datum und einmal ohne).
  • Sie können auch STATISTICS IO verwenden, um den Unterschied anzuzeigen.
  • Wenn Sie über genügend Testdaten verfügen, ist der Unterschied leicht erkennbar.

Sobald Sie die Beweise haben, schlage ich vor, dass Sie sie mit dem DBA aufnehmen. Lassen Sie sich jedoch nicht auf einen Streit ein. Zeigen Sie einfach den Test und die Daten, die zeigen, dass der Index verwendet wird.

Der Punkt ist, dass Sie nicht gezwungen werden möchten, sich nach hinten zu beugen, um nicht vorhandene Probleme zu vermeiden.

Glücklicherweise ist es in dem von Ihnen demonstrierten Fall kein Problem, die Funktionen außerhalb der Abfrage zu verschieben. Z.B

DECLARE @FromDate date ='inputdate',
        @ToDate date = DATEADD(day, 1, @FromDate)

In der Tat kann das Obige auf lange Sicht sogar wartbarer sein.

Es wird jedoch eine Zeit kommen, in der Sie etwas haben, das nicht trivial nach den Wünschen des DBA geändert werden kann. Sowie:

--Granted this probably belongs in a JOIN clause, but is primarily for illustrative purposes.
--Also the issue of sargability applies just as much to JOIN clauses as WHERE clauses
WHERE a.date >= b.date
  AND a.date < DATEADD(day, 1, b.date)

Die einzige Möglichkeit, diese Funktion aus der WHERE-Klausel herauszuholen, besteht darin, eine andere Spalte vorab zu berechnen b.NextDay. Genau aus diesem Grund benötigen Sie die Datenbankadministratoren, um die Sargabilität richtig zu verstehen. Dh das oben genannte:

  • Wäre in der Lage, einen Index auf zu nutzen a.date.
  • Aber nicht in der Lage sein, einen Index zu nutzen b.date.
  • Auf die selektivste Spalte / den selektivsten Index sollte also keine Funktion angewendet werden, auf die andere.
  • Der Versuch, eine Lösung ohne eine Funktion in der WHERE-Klausel zu hacken, verringert sowohl die Wartbarkeit als auch die Leistung.

Wenn Sie wirklich kein Buy-In von den DBAs erhalten können, funktioniert möglicherweise Folgendes und umgeht deren Regeln für den Frachtkult:

;WITH CTE_B AS (
    SELECT  b.Date, DATEADD(day, 1, b.DATE) AS NextDay
    FROM    b
    )
SELECT  ...
WHERE   a.Date >= CTE_B.Date
    AND a.Date < CTE_B.NextDay

Der Optimierer wird dies mit ziemlicher Sicherheit auf die gleiche Weise optimieren, als ob die Funktion in der WHEREKlausel enthalten wäre, sodass Sie keinen Leistungsverlust erhalten sollten. Aber es ist sicherlich eine unnötige Verringerung der Wartbarkeit.

Desillusioniert
quelle
Das wird schlecht klingen, aber ich lebe in der Steinzeit. CTEs werden nicht funktionieren. WITHwird nicht funktionieren ... zumindest vorerst nicht. Alle Abfragen werden über ein Berichtssystem ausgeführt, das vordefinierte Anweisungen akzeptiert. Die gleichen, die ich geerbt habe. Mein ultimativer Plan ist es, alles auf Skripte zu verschieben, die die Arbeit automatisch erledigen und derzeit manuell ausgeführt werden. Ja, die Datenbankadministratoren können CTEs verwenden, und tatsächlich haben sie einen Plan wie Ihren vorgeschlagen. Und ich möchte nicht mit ihnen in einen Pisswettbewerb geraten, weil sie das Leben schwer machen können.
Sten
Ich möchte auch nicht den guten Willen verlieren, den ich gewonnen habe, als ich der erste der Analyse-Leute war, der tatsächlich zu ihnen ging und fragte, was sie denken, bevor sie Code auf dem Produktionsserver ausführten. Politik.
Sten