11

値が渡されない場合、後で現在の日付に設定される日付入力を受け入れるストアド プロシージャがあります。

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

@MyDateストアド プロシージャが最初にコンパイルされたときに渡されたNULL場合、すべての入力値 (またはそれ以外) のパフォーマンスが常にひどいという問題がありNULLますが、ストアド プロシージャがコンパイルされたときに日付/現在の日付が渡された場合すべての入力値 (NULLまたはそれ以外)のパフォーマンスは良好です。

また紛らわしいのは、使用される @MyDate の値が実際に NULL(かつCURRENT_TIMESTAMPIF ステートメントによって設定されていない)場合でも、生成される貧弱な実行計画がひどいことです。

パラメータ スニッフィングを無効にすると (パラメータをスプーフィングして)、問題が解決することがわかりました。

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

これはパラメーターのスニッフィングと関係があることは知っていますが、「パラメーターのスニッフィングがうまくいかなかった」という例はすべて、渡された代表的でないパラメーターを使用してコンパイルされたストアド プロシージャに関係していましたが、ここで私はそれを見ています実行計画はNULL、ステートメントが実行される時点でパラメーターが取る可能性があるとSQLサーバーが考える可能性のあるすべての考えられる値に対してひどいものです-CURRENT_TIMESTAMPまたはその他。

なぜこれが起こっているのか、誰かが洞察を得ましたか?

4

3 に答える 3

8

基本的にはい - SQL Server 2005 のパラメーター スニッフィング (一部のパッチ レベル) はひどく壊れています。パラメータがマスクされると数秒で完了するデータの小さな (数千行) セットであっても、実際には (小さなデータ セットでは数時間以内に) 完了しない計画を見てきました。これは、パラメータが常に同じ数値であった場合です。これに対処していると同時に、LEFT JOIN/NULLが完了しないという多くの問題を発見し、それらをNOT INまたはNOT EXISTSに置き換え、これにより計画が完了するものに解決されたことを付け加えます。繰り返しますが、(非常に貧弱な) 実行計画の問題です。私がこれに対処していたとき、DBA は私に SHOWPLAN アクセスを許可しませんでした。私はすべての SP パラメータをマスキングし始めたので、

SQL Server 2008 では、OPTIMIZE FOR UNKNOWN.

于 2009-06-17T14:40:33.557 に答える
1

(SQL Server 2005) でこの問題を回避する方法の 1 つは、ローカル パラメーターを再宣言してパラメーターをマスクする代わりに、クエリ オプティマイザーのヒントを追加することでした。

これについて詳しく説明している良いブログ投稿は次のとおりです 。SqlServer 2005 でのパラメーター スニッフィング

私が使用した: OPTION (optimize for (@p = '-1'))

于 2009-09-25T23:09:08.973 に答える