Haben Datenbank-Engines andere als SQL Server verhalten sich diese Art und Weise?
-
05-10-2019 - |
Frage
Ich habe eine gespeicherte Prozedur, die so etwas wie dieses (Pseudo-Code) geht
storedprocedure param1, param2, param3, param4
begin
if (param4 = 'Y')
begin
select * from SOME_VIEW order by somecolumn
end
else if (param1 is null)
begin
select * from SOME_VIEW
where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
and (param3 is null or param3 = SOME_VIEW.SomeColumn3)
order by somecolumn
end
else
select somethingcompletelydifferent
end
Alle liefen gut für eine lange Zeit. Plötzlich begann die Abfrage läuft immer, wenn param4 war ‚Y‘. Ändern Sie den Code so aus:
storedprocedure param1, param2, param3, param4
begin
if (param4 = 'Y')
begin
set param2 = null
set param3 = null
end
if (param1 is null)
begin
select * from SOME_VIEW
where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
and (param3 is null or param3 = SOME_VIEW.SomeColumn3)
order by somecolumn
end
else
select somethingcompletelydifferent
Und es läuft wieder innerhalb der erwarteten Parameter (15 Sekunden oder so für 40.000 Datensätze). Dies ist mit SQL Server 2005. Der Kern meiner Frage ist dieses besondere „Feature“ spezifisch für SQL Server, oder ist dies ein gemeinsames Merkmal unter RDBMS‘im Allgemeinen, dass:
- Abfragen, dass lief gut zwei Jahre lang arbeiten nur stoppen, wenn die Daten wächst.
- Der „neue“ Ausführungsplan zerstört die Fähigkeit des Datenbankservers die Abfrage auch wenn eine logisch äquivalente Alternative läuft ganz gut? auszuführen
Das mag wie eine Tirade gegen SQL Server scheinen, und ich bis zu einem gewissen Grad nehme an, es ist, aber ich möchte wirklich wissen, ob andere diese Art von Realität erleben mit Oracle, DB2 oder andere RDBMS. Obwohl ich einige Erfahrung mit anderen habe, habe ich nur diese Art von Volumen und die Komplexität auf SQL Server gesehen, so dass ich neugierig bin, wenn andere mit großen, komplexen Datenbanken in anderen Produkten ähnliche Erfahrung haben.
Lösung
Es könnte ein paar Ursachen
1) werden die Statistiken aktuell?
2) Sie leiden an Parameter sein könnte Sniffing
BTW für diese Art von Sachen
where (param2 ist null oder param2 = SOME_VIEW.Somecolumn2)
Werfen Sie einen Blick auf Haben Sie Spalte verwenden = @ Param OR @param IS NULL in Ihrer WHERE-Klausel? Sie nicht, es führt keine
Andere Tipps
würde ich diese bestimmte Instanz des Problems vorstellen, und alle Bedingungen, die führen zu diesem Ereignisse sind spezifisch für SQL Server - wahrscheinlich sogar die Ausgabe. (Zum Beispiel SQL Server 2008 würde sich anders verhalten.)
Das ist aber ein generelles „Feature“ des Abfrageoptimierer. Sie schauen auf Ihre Anfrage und versuchen, eine fundierte Vermutung, zu machen, was die schnellste ausführen wird. Da die Nutzer, wir haben wenig direkte Kontrolle, wenn das Optimierungsprogramm wählt (sagen sie) ein Index-Scan oder ein Index Seek, aber es indirekt, indem sie alternative Wege zum Ausdruck zu bringen, die gleiche Sache, beeinflussen kann, zu sehen, ob die Invokes Ausführungszeit verbessert.
Wenn gibt es keine weiteren Änderungen am Schema gewesen, den die Abfrage beeinflussen könnte, dann prüfen, ob die Indexstatistiken aktualisiert werden. Wir verwenden einen wöchentlichen Batch-Job, dies zu tun.