1. ホーム
  2. sql

[解決済み】OPTION(RECOMPILE)の方が常に速い、なぜ?

2022-04-13 10:26:11

質問

を追加すると、奇妙な状況に遭遇しました。 OPTION (RECOMPILE) を省略すると、クエリの実行に5分以上かかってしまいます。

これは、Query Analyzerからクエリを実行した場合と、私のC#プログラムから SqlCommand.ExecuteReader() . を呼び出す(または呼び出さない)。 DBCC FREEPROCCACHE または DBCC dropcleanbuffers を指定した場合、クエリの結果は常に即座に返されます。 OPTION (RECOMPILE) 5分以上かかる。クエリーは常に同じパラメータで呼び出されます(このテストのため)。

SQL Server 2008を使用しています。

SQLの記述にはかなり慣れているのですが、これまで一度も OPTION コマンドをクエリで使用したことがなく、このフォーラムの投稿を読むまでプランキャッシュの全体的な概念になじみがなかったのです。私が投稿から理解したのは、以下の通りです。 OPTION (RECOMPILE) は高価な操作です。どうやら、クエリに対して新しい検索ストラテジーを作成するようです。ではなぜ、その後のクエリで OPTION (RECOMPILE) はこんなに遅いのでしょうか?リコンパイルヒントを含む前回の呼び出しで計算されたルックアップ戦略を、その後のクエリで使用するべきではないでしょうか?

1回呼び出すごとにリコンパイルヒントが必要なクエリというのは、非常に珍しいことなのでしょうか?

初歩的な質問で申し訳ないのですが、いまいちピンとこないのです。

UPDATE: クエリを掲載するように言われたのですが・・・。

select acctNo,min(date) earliestDate 
from( 
    select acctNo,tradeDate as date 
    from datafeed_trans 
    where feedid=@feedID and feedDate=@feedDate 

    union 

    select acctNo,feedDate as date 
    from datafeed_money 
    where feedid=@feedID and feedDate=@feedDate 

    union 

    select acctNo,feedDate as date 
    from datafeed_jnl 
    where feedid=@feedID and feedDate=@feedDate 
)t1 
group by t1.acctNo
OPTION(RECOMPILE)

Query Analyzerからテストを実行するときは、以下の行を先頭につけています。

declare @feedID int
select @feedID=20

declare @feedDate datetime
select @feedDate='1/2/2009'

C# プログラムから呼び出す場合、パラメータは SqlCommand.Parameters プロパティを使用します。

この議論では、パラメータは決して変更されないと仮定して、最適でないパラメータの匂いを原因として除外することができます。

どのように解決するのか?

を使用する場合があります。 OPTION(RECOMPILE) は意味があります。 私の経験では、これが有効な選択肢となるのは、動的SQLを使用しているときだけです。 あなたの状況において、この方法が理にかなっているかどうかを検討する前に、統計情報を再構築することをお勧めします。 これは、次のように実行することで可能です。

EXEC sp_updatestats

そして、実行計画を再作成します。 こうすることで、実行計画が作成されるときに、最新の情報が使用されるようになります。

追加 OPTION(RECOMPILE) は、クエリ実行のたびに実行計画を再構築します。 という表現は聞いたことがありません。 creates a new lookup strategy しかし、私たちは同じものを違う言葉で表現しているだけなのかもしれません。

ストアドプロシージャが作成されると(.NETからアドホックなSQLを呼び出しているのだろうと思いますが パラメータ化されたクエリを使用している場合、これは結局ストアド プロシージャの呼び出しとなります。 ) SQL Server は、データベース内のデータと渡されたパラメータに基づいて、このクエリの最も効果的な実行計画を決定しようとします ( パラメータスニッフィング ) を作成し、このプランをキャッシュします。つまり、データベースに10件のレコードがあるときにクエリを作成し、100,000,000件のレコードがあるときに実行すると、キャッシュされた実行プランが最も効果的でなくなる可能性があるということです。

要約すると、私は OPTION(RECOMPILE) は、ここで利益をもたらすでしょう。 統計情報と実行計画の更新が必要なだけではないでしょうか。 統計情報の再構築は、状況によってはDBAの仕事の不可欠な部分となり得ます。 統計情報を更新してもまだ問題があるようなら、両方の実行計画を投稿することをお勧めします。

クエリを実行するたびに実行計画を再コンパイルすることが最良の選択であることは、非常に珍しいと言えるでしょう。