ストアドプロシージャのキャッシュから計画が欠落する理由は何ですか?
WITH RECOMPILE
- 動的SQL
- 暗号化されたコード
- 重要なデータ変更
- 統計を更新する
- ほかに何か?
最近、2つのサーバー(SQL Server 2008 R2およびSQL Server 2012)で作業しましたが、非常にリソースを消費するストアドプロシージャのキャッシュに計画がありませんでした。ストアドプロシージャ内のステートメントの多く(おそらくすべて)にも、キャッシュに計画がありませんでした。一部のストアドプロシージャは、1秒間に数回のようにかなり頻繁に実行されます。
メモリーのプレッシャーは一切ありません。サーバーの1つには、必要以上のハードウェアが搭載されています。
不足している計画は、ストアドプロシージャの途中で一時テーブルが作成されたためだと思いましたが、それはSQL Server 2000以前の古い情報のようです。SQL Server 2005以降、DDLの後のステートメントのステートメントレベルで再コンパイルが行われます。それはすべての場合に当てはまりますか、それとも新しいバージョンでも発生しますか?
不足している計画の原因は他に何でしょうか?このトピックに関するいくつかの記事をざっと読みましたが、何も当てはまらないようです。
アドホックワークロードの最適化は、今週見ているサーバーで有効になっています。ストアドプロシージャの1つは1日に1回のみ実行されます。私はそのためのコードを持っています。1分間に100回以上実行するコードはありませんが、入手できます。コードを投稿することはできませんが、質問に関連して説明できます。
プロシージャキャッシュを解放したり、クリーンバッファを削除したりする人はいないと思います。このクライアントは、監視ツールの1つとしてSolarwinds DPAを使用しています。DPAは、1日に1回呼び出されるストアドプロシージャ内のステートメントの実行計画の1つをキャプチャしました。その文には、引数なしのWHERE
句のために大量の読み取りがあります。DPAがステートメントをキャプチャした場合、それは推定プランであり、一度にプランキャッシュ内にありました。トラブルシューティングを行っているときは、そこにはありません。sp_WhoIsActive
テーブルへのロギングを開始します。
を使用していsp_BlitzCache
ます。(私はBrent Ozar Unlimitedで働いています)これにより、ストアドプロシージャ全体の計画と、個々のステートメントの計画(存在する場合)が表示されます。存在しない場合は、「このクエリのプランが見つかりませんでした。これには、動的SQL、RECOMPILE
ヒント、暗号化コードが考えられます」という警告が表示されます。そして、その警告は声明にもあります。
TF 2371は設置されていません。待機状況を確認しています。サーバーはかなり退屈です。PLEは130,000を超えています。
これで、さらに2つのストアドプロシージャのコードを入手できました。そのうちの1つは、動的SQLを使用しているexec (@sql)
ので、なぜ計画がないのかがわかります。しかし、もう1つは、これは1分間に100回以上実行されているもので、異常なものは何もありません。その中で際立っている唯一のものは、一時テーブルが1000行を超えるコードの途中で作成されていることです。たくさんの子ストアドプロシージャも呼び出します。
SQL Server 2008のプランキャッシュに関して、8k以上のリテラルは表示されませんが、ストアドプロシージャの1つには、別のストアドプロシージャを呼び出す直前に一括挿入に関するコメントがあります。しかし、私が見ている外部ストアドプロシージャには一括挿入は表示されません。この記事の「再コンパイルのしきい値」セクションは興味深いものです。一時テーブルで私が目にしているのは、大量のINSERT(何百万行になる可能性がある)、いくつかの更新と削除です。そのため、一時テーブルに多くのデータが変更されます。数百万。