1

非常に高速(1秒)で実行されるクエリがあります。以下を参照してください。

SELECT *
FROM    ( select ROW_NUMBER() OVER ( ORDER BY  [Rank] DESC ) AS RowNum, *
          FROM [product].[FnSearchKeyword]('basic', null, null, null, null, null, null,           null)
    ) AS RowConstrainedResult
WHERE   RowNum     = 1 AND RowNum < 30

このクエリをプロシージャ内に配置すると、次のように実行するのに15秒かかります。

 CREATE  anydata 
    @keywords nvarchar(4000),
    @minimunRate int, 
    @priceFrom decimal, 
    @priceTo decimal, 
    @relaeseStart datetime,
    @releaseEnd datetime,
    @categoryList nvarchar(4000), 
    @storeList nvarchar(4000),
    @rowBegin int,
    @rowEnd int,
    @orderBy int,
    @isAdult bit = null
 AS 
 SELECT *
 FROM    ( select ROW_NUMBER() OVER ( ORDER BY  [Rank] DESC ) AS RowNum, *
           FROM [product].[FnSearchKeyword]('basic', @minimunRate , @priceFrom , @priceTo      , null, null, null, null)
    ) AS RowConstrainedResult
 WHERE   RowNum     = 1 AND RowNum < 30

SQLを再生すると、戻り遅延は15秒になります。

 exec anydata  null, null, null, null, null, null, null, null, null, null, null

ノート:

  • 関数FnSearchKeywordのパラメーターは、AnyDataプロシージャで宣言されたタイプと同じです。

  • execプロシージャですべての値「NULL」を渡して、上記のクエリと同じ結果を高速で実行します。パラメータの範囲に変更はありません

正直なところ、プロシージャを介してクエリを実行すると「実行プラン」が変更されることに気付きましたが、クエリのパラメータが同じであるため、これを解決する方法がわかりません。

残念ながら、問題をさらに複雑にしないために、ここに記載されていない他の理由でPROCクエリ内に配置する必要があります。

重複したメッセージについて:どのシステム(Query Analyzer、C#asp.net、その他)でも実行が遅いため、質問は重複していません。

4

1 に答える 1

4

ストアドプロシージャのパラメータは同じになりましたが、プランが最初にキャッシュされたときは何でしたか?を追加することで、パラメータのスニッフィングを阻止できますOPTION RECOMPILE

2008以降(バージョンを指定してください!)の場合、ステートメント自体は同じプランを使用する必要があるため、セッションとストアドプロシージャのSET設定も確認する必要があります。たとえば、一方をARITHABORTオンにし、もう一方をオンにしないと、異なる計画につながる可能性があります。異なる計画がある場合、一方が悪い場合と他方が良い場合があります。また、クエリテキスト内のスペースが1つでも異なると、SQLServerはそれらを2つの異なるプランとして扱う可能性があることにも注意してください。

設定とクエリテキストを同じにすることで、これらのプランの違いを回避できますが、この方法でパラメータスニッフィングの問題を制御することはできません。それがパラメータスニッフィングの問題である場合は、実験することもできますOPTIMIZE FOR...

于 2013-02-21T18:19:41.887 に答える