sp_executesqlはクエリプランをいつ更新しますか?


13

私はDBAではないので、私の素朴さを許さなければなりませんが、データベースの変更とストアドプロシージャの統計を時間の経過とともに再コンパイルして、クエリプランを最新の統計で最新に保つ必要があることを理解しています。

私が最新の統計に対して再コンパイルされた私のデータベース内のストアドプロシージャ持つと仮定すると、いくつかのコードでストアドプロシージャをインライニングとそれを包むの意味するものは、一定の間隔をsp_executesql文では?プロシージャの再コンパイルの一部として行われていたクエリプランの更新が失われますか?

この変更を行う前に考慮する必要のあるもの(権限以外)があれば、あなたの洞察に感謝します。

私はMSDNでこれを読みました:

SQL Serverクエリオプティマイザーが既存の実行プランと新しいTransact-SQL文字列を一致させる機能は、特に複雑なTransact-SQLステートメントで、文字列のテキストのパラメーター値が絶えず変化することによって妨げられます。

だから、私がインラインしてラップしようとしているストアドプロシージャにsp_executesql実際にいくつかのパラメータが含まれていると仮定すると、これは私の実行計画がキャッシュされているが、SQL Serverがそれを見つけて再利用することをより難しくしているということですか?

回答:


7

MSDNの行ではEXEC()、次のようにの使用について説明しています。

SET @sql = 'SELECT foo FROM dbo.bar WHERE x = ''' + @x + ''';';
EXEC(@sql);

私のテストでは、SQL Serverの最新バージョンはまだこのようなプランを再利用できますが、他の変数(バージョンなど、またはWHERE特定のパラメーターの存在に基づいて条件句を追加する場合など)が存在する場合があります。別のプランを生成します)。

使用するsp_executesqlと、パラメーター値はパラメータースニッフィングの問題を引き起こす可能性があります(通常のSQLと同様)が、これはSQL Serverがプランを再利用できるかどうかとは関係ありません。このプランはsp_executesql、直接クエリを再コンパイルする変数を除き、まったく使用していないかのように何度も繰り返し使用されます。その場合、このプランも再コンパイルされます(基本的に、SQL Serverは「これはsp_executesqlから実行されましたが、これはそうではありませんでした」というプランで何かを保存します。

SET @sql = N'SELECT foo FROM dbo.bar WHERE x = @x;';
EXEC sp_executesql @sql, N'@x VARCHAR(32)', @x;

ボーナスとして、これには動的SQLに対する組み込みの保護があり、文字列の区切り文字による単一引用符の二重化を心配する必要がありません。このことの一部をここでブログに書きました

あなたは計画の再利用および/またはパラメータが盗聴に問題がある場合は、あなたがになりますいくつかのものがありOPTION (RECOMPILE)OPTIMIZE FORoptimize for ad hoc workloadssimple/forced parameterization。私はここで最近のウェブキャストへの応答としていくつかの同様の質問に答えました、それは一見の価値があるかもしれません:

http://sqlperformance.com/performance-palooza

要点は次のとおりです。を使用することを恐れないでsp_executesqlください。必要なときにのみ使用し、実際のパフォーマンスの問題が発生した場合にのみ最適化にエネルギーを費やしてください。上記の例は恐ろしいものです。なぜなら、ここでは動的SQLを使用する理由がないからです。正当なユースケースがあると仮定して、この答えを書きました。


2

sp_executesqlを介して実行されるクエリは、sp_executesqlを介して実行されない通常のクエリと同じ実行プランのルールに従います。クエリテキストが変更されると、新しいプランが作成されます。パラメータのユーザーが原因でテキストが変更されない場合、プランは再利用されます。統計が更新されると、プランが期限切れになり、次回クエリが実行されたときに新しいプランが生成されます。


あなたの答えをありがとう、sp_ExecuteSqlを呼び出すたびにクエリとして異なる文字列を使用することに気付いたので、SQL Serverの観点から、ハードコードされた値を持つパラメーター(クエリをSql Serverに送信する前にコードで入力されます)。これを回避する方法を知っていますか?インラインsqlステートメントで変数を宣言すると、クエリオプティマイザーがキャッシュされたクエリプランを見つけるのに役立ちますか?
ジェームズルイス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.