Ich habe die folgende Abfrage:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
Die obige Abfrage ist in drei Sekunden abgeschlossen.
Wenn die obige Abfrage einen Wert zurückgibt, soll die gespeicherte Prozedur EXIT sein. Deshalb habe ich sie wie folgt umgeschrieben:
If Exists(
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
)
Begin
Raiserror('Source missing',16,1)
Return
End
Dies dauert jedoch 10 Minuten.
Ich kann die obige Abfrage wie folgt umschreiben, was auch in weniger als 3 Sekunden erledigt ist:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source
if @@rowcount >0
Begin
Raiserror('Source missing',16,1)
Return
End
Das Problem bei der obigen Umschreibung ist, dass die obige Abfrage Teil einer größeren gespeicherten Prozedur ist und mehrere Ergebnismengen zurückgibt. In C # durchlaufen wir jede Ergebnismenge und führen eine Verarbeitung durch.
Das oben Gesagte gibt eine leere Ergebnismenge zurück. Wenn ich mich für diesen Ansatz entscheide, muss ich mein C # ändern und die Bereitstellung erneut durchführen.
Also meine Frage ist,
Warum ändert die Verwendung von nur
IF EXISTS
den Plan, um so viel Zeit in Anspruch zu nehmen?
Nachfolgend finden Sie die Details, die Ihnen helfen können, und lassen Sie mich wissen, wenn Sie weitere Details benötigen:
- Erstellen Sie ein Tabellen- und Statistikskript, um denselben Plan wie meinen zu erhalten
- Zeitlupenplan
Schneller Ausführungsplan
Langsamer Plan mit Brentozar Plan einfügen
Schneller Plan mit Brentozar Plan einfügen
Hinweis: Beide Abfragen sind identisch (mithilfe von Parametern). Der einzige Unterschied besteht darin, dass EXISTS
ich bei der Anonymisierung möglicherweise einige Fehler gemacht habe.
Die Tabellenerstellungsskripts sind unten aufgeführt:
http://pastebin.com/CgSHeqXc - kleine Tabellenstatistik
http://pastebin.com/GUu9KfpS - große Tabellenstatistik