Heute hatte ich ein Problem mit einem Zeitlimit für gespeicherte Prozeduren (das länger als 30 Sekunden dauerte), als es von einer ASP.NET-Webseite ausgeführt wurde, das jedoch schnell ausgeführt wurde, wenn es von SSMS ausgeführt wurde (dauerte 5 Sekunden).
Nachdem ich den Verdacht hatte, dass Parameter als Schuldiger geschnüffelt wurden, maskierte ich die Eingabeparameter und die Abfrage wurde schneller ausgeführt.
Meine Frage ist: Warum ist das passiert?
Dieses System ist seit mehr als 5 Jahren in Produktion und dies ist das erste Mal, dass wir so etwas auf unseren gespeicherten Prozeduren sehen. Ist das "Datenbankverschleiß"?
Wir haben das Problem gelöst, es ist also keine große Sache, aber ich bin nur neugierig, warum dies geschah.
sql-server
stored-procedures
query-performance
parameter
Zwiebelritter
quelle
quelle
DROP
/CREATE PROC
.sql-Dateien füge ich normalerweise einEXEC
for the sproc mit realistischen Parametern ein. Jedes Mal, wenn der Sproc neu erstellt wird, wird er einmal mit guten Parametern ausgeführt und (sollte) einen guten Ausführungsplan erhalten.Antworten:
Wenn SQL Server eine Abfrage sieht, die kompiliert werden muss, verwendet es im Grunde genommen die erstmalig aufgerufenen Parameter, um den Ausführungsplan zu generieren. Dies kann eine gute Sache sein oder auch nicht, aber es ist das, was passiert.
Angenommen, Sie haben eine Obsttabelle (100 Zeilen). Es gibt 98 Reihen, die Apfel sind, und nur 2 Reihen, die die Fruchtorange enthalten. Wenn Sie diese Tabelle nach Apple abfragen, wird der Plan höchstwahrscheinlich mit einem Scan kompiliert. Dies ist eine gute Sache, da es für diese Apple-Abfrage optimiert ist. Wenn Sie jedoch nach Orange fragen möchten, ist dieser Scan ineffizient. Es wird jedoch der gespeicherte Plan verwendet.
Tatsache ist, dass es passiert. Es passiert ständig. Es ist normalerweise kein offenes Problem, aber in einigen Fällen kann es ein ziemlich großes Problem sein. Eine Lösung für ein anhaltend schlechtes Problem beim Sniffing von Parametern besteht darin, dass Sie den
OPTIMIZE FOR
Abfragehinweis verwenden können, um SQL Server zu zwingen, bestimmte Parameterwerte beim Generieren des Ausführungsplans bei der ersten Kompilierung zu verwenden.quelle
OPTIMIZE FOR UNKNOWN
oderOPTION RECOMPILE
wenn die Planform stark variiert und es keinen einzigen Wert gibt, für den Sie wissentlich optimieren können.OPTION RECOMPILE
, da ich mich lieber mit einem nicht optimalen zwischengespeicherten Plan befassen würde, als für jeden Anruf neu zu kompilieren.OPTION RECOMPILE
ist dies besser - der Kompilierungsaufwand kann im Vergleich zu einem wirklich schlechten Plan gering sein.OPTION RECOMPILE
und späteroptimize for ad hoc workloads
wirklich geholfen.Eher ärgerlich ist, dass die SSMS-Standardeinstellung für
SET ARITHABORT ON
die meisten Client-Bibliotheken (ADO .Net, ODBC, OLE DB) angegeben istSET ARITHABORT OFF
. Wahrscheinlich hatten Sie einen Plan "schlecht", aber als Sie versuchten, über SSMS zu replizieren, führte der Unterschied in ARITHABORT dazu, dass ein anderer Plan verwendet wurde, der "gut" war.Langsam in der Anwendung, schnell in SSMS? ist eine gute Referenz dafür.
Höchstwahrscheinlich wurde eine Neukompilierung ausgelöst und leider wurde ein nicht typischer Satz von Eingaben für die Kompilierung verwendet.
quelle