2009-06-17 13 views
9

ich eine gespeicherte Prozedur, die eine Datumseingabe akzeptiert, die später auf das aktuelle Datum gesetzt wird, wenn kein Wert übergeben wird:SQL schlecht gespeicherte Prozedur Ausführungsplan Performance - Parameter Sniffing

CREATE PROCEDURE MyProc 
    @MyDate DATETIME = NULL 
AS 
    IF @MyDate IS NULL SET @MyDate = CURRENT_TIMESTAMP 
    -- Do Something using @MyDate 

bin ich mit Problemen Wenn @MyDate als NULL übergeben wird, wenn die gespeicherte Prozedur zuerst kompiliert wird, ist die Leistung immer schrecklich für alle Eingabewerte (NULL oder andere), wenn ein Datum/das aktuelle Datum übergeben wird, wenn die gespeicherte Prozedur kompiliert wird in Ordnung für alle Eingabewerte (NULL oder anders).

Was auch verwirrend ist, dass der schlechte Ausführungsplan, der in schrecklich selbst erzeugt wird, wenn der Wert von @MyDate verwendete ist eigentlichNULL (und nicht auf CURRENT_TIMESTAMP durch die IF-Anweisung)

I‘ habe entdeckt, dass (durch spoofing den Parameter) behebt mein Problem Sniffing Parameter zu deaktivieren:

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 

ich weiß, das etwas mit dem Parameter Sniffing zu tun ist, aber alle Beispiele ich je gesehen habe „Parameter Sniffing gone bad“ habe die gespeicherte Prozedur be handelt Ich habe gesehen, dass der Ausführungsplan für alle erdenklichen Werte schrecklich ist, die der SQL-Server möglicherweise für den Punkt hält, an dem die Anweisung ausgeführt wird - NULL, CURRENT_TIMESTAMP oder auf andere Weise .

Hat jemand einen Einblick, warum das passiert?

+1

Das ist interessant, aber du bist nicht wirklich irgendwo eine Frage zu stellen ... – cjk

+0

Das ist mir gerade aufgefallen :-) – Justin

Antwort

6

Grundsätzlich ja - Parameter Sniffing (in einigen Patch-Ebenen) von SQL Server 2005 ist stark beschädigt. Ich habe Pläne gesehen, die selbst bei kleinen (einige tausend Zeilen) Datensätzen, die in Sekunden abgeschlossen werden, wenn die Parameter maskiert sind, niemals wirklich abgeschlossen werden (innerhalb weniger Stunden auf einem kleinen Datensatz). Und dies ist in Fällen, wo der Parameter immer die gleiche Nummer war. Ich würde hinzufügen, dass ich zur gleichen Zeit, mit der ich damit zu tun hatte, viele Probleme mit LEFT JOIN/NULLs nicht abgeschlossen hatte und ich ersetzte sie durch NOT IN oder NOT EXISTS und dies löste den Plan zu etwas, das abgeschlossen wäre. Auch hier ein (sehr schlechter) Ausführungsplan. Zu der Zeit, als ich damit zu tun hatte, gaben mir die DBAs keinen SHOWPLAN-Zugriff, und da ich jeden SP-Parameter maskierte, hatte ich keine weiteren Ausführungsplanprobleme, bei denen ich mich wegen der Nichtvollendung einmischen müsste .

In SQL Server 2008 können Sie OPTIMIZE FOR UNKNOWN verwenden.

0

Eine Möglichkeit, dieses Problem in (SQL Server 2005) zu umgehen, anstatt nur die Parameter zu maskieren, indem lokale Parameter neu deklariert wurden, war das Hinzufügen von Abfrageoptimiererhinweisen.

Hier ist eine gute Blog-Post, die mehr darüber spricht: Parameter Sniffing in SqlServer 2005

I verwendet: OPTION (Optimierung für (@p = '1'))

Verwandte Themen