Leistung des Ausführungsplans für SQL-schlechte gespeicherte Prozeduren - Parameter-Sniffing
Ich habe eine gespeicherte Prozedur, die eine Datumseingabe akzeptiert, die später auf das aktuelle Datum gesetzt wird, wenn kein Wert übergeben wird:
<code>CREATE PROCEDURE MyProc @MyDate DATETIME = NULL AS IF @MyDate IS NULL SET @MyDate = CURRENT_TIMESTAMP -- Do Something using @MyDate </code>
Ich habe Probleme damit wenn@MyDate
wird übergeben alsNULL
Wenn die gespeicherte Prozedur zum ersten Mal kompiliert wird, ist die Leistung für alle Eingabewerte immer schlecht (NULL
oder anders), wobei, wenn ein Datum / das aktuelle Datum übergeben wird, wenn die gespeicherte Prozedur kompiliert wird, die Leistung für alle Eingabewerte in Ordnung ist (NULL
oder andernfalls).
Was auch verwirrend ist, ist, dass der schlechte Ausführungsplan, der in generiert wird, schrecklich ist, selbst wenn der Wert von @MyDate verwendet wirdtatsächlich NULL
(und nicht eingestellt aufCURRENT_TIMESTAMP
durch die IF-Anweisung)
Ich habe festgestellt, dass das Deaktivieren von Parameter-Sniffing (durch Spoofing des Parameters) mein Problem behebt:
<code>CREATE PROCEDURE MyProc @MyDate DATETIME = NULL AS DECLARE @MyDate_Copy DATETIME SET @MyDate_Copy = @MyDate IF @MyDate_Copy IS NULL SET @MyDate_Copy = CURRENT_TIMESTAMP -- Do Something using @MyDate_Copy </code>
Ich weiß, dass dies etwas mit Parameter-Sniffing zu tun hat, aber bei allen Beispielen, die ich für "Parameter-Sniffing inaktiv" gesehen habe, wurde die gespeicherte Prozedur mit einem nicht repräsentativen übergebenen Parameter kompiliert Der Ausführungsplan ist für alle denkbaren Werte schrecklich, von denen SQL Server annimmt, dass der Parameter an dem Punkt, an dem die Anweisung ausgeführt wird, möglicherweise einen Wert annimmt.NULL
, CURRENT_TIMESTAMP
oder andernfalls.
Hat jemand einen Einblick, warum dies geschieht?