ストアドプロシージャのキャッシュからプランが欠落する理由は何ですか?
WITH RECOMPILE
_最近、2つのサーバー(SQL Server 2008 R2とSQL Server 2012)で作業しましたが、非常にリソースを大量に消費するストアドプロシージャのキャッシュに計画がありませんでした。ストアドプロシージャ内のステートメントの多く、おそらくすべても、キャッシュに計画がありませんでした。一部のストアドプロシージャは、毎秒数回など、かなり頻繁に実行されます。
全くメモリプレッシャーはありません。サーバーの1つに、必要以上のハードウェアが搭載されています。
欠けている計画は、ストアドプロシージャの途中で一時テーブルが作成されたためだと思いましたが、SQL Server 2000以前の古い情報のようです。 SQL Server 2005以降、DDLの後のステートメントのステートメントレベルで再コンパイルが行われます。それはすべての場合に当てはまりますか、それとも新しいバージョンでも発生しますか?
不足している計画の原因は他に何でしょうか?このトピックに関するいくつかの記事を読み飛ばしましたが、何も当てはまらないようです。
今週見ているサーバーで、アドホックワークロードの最適化が有効になっています。ストアドプロシージャの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つは、exec (@sql)
で動的SQLを使用しているため、計画がないのはなぜでしょうか。しかし、もう1つは、これが1分あたり100回以上実行されているものであり、異常なことは何もありません。その中で際立っている唯一のことは、一時テーブルが1000行を超えるコードの途中で作成されていることです。多数の子ストアドプロシージャも呼び出します。
SQL Server 2008のプランキャッシュ に関して、リテラル> = 8kが表示されませんが、ストアドプロシージャの1つに、別のストアドプロシージャを呼び出す直前に一括挿入に関するコメントがあります。しかし、私が見ている外部ストアドプロシージャには一括挿入が表示されません。記事の「再コンパイルのしきい値」セクションは興味深いものです。一時テーブルについて私が見ているのは、大量のINSERT(数百万行になる可能性があります)、いくつかの更新と削除です。そのため、一時テーブルに大量のデータが変更されます。何百万。
2つのプランキャッシュDMFがあります。
sys.dm_exec_query_plan-キャッシュされたプランをXML形式で返しますが、特定のサイズまでです(ただし、 SQL ServerではXMLとしてフォーマットできます。つまり、最大128のネストされたレベルになります。)
sys.dm_exec_text_query_plan-キャッシュされたプランを任意のサイズのテキスト形式で返します。ただし、欠点は、プランが大きい場合、SQL Server内でプランをXMLに変換できず、XMLがnullを返すためTRY_CONVERTでさえできないことです。
sp_BlitzCacheは以前のDMVにのみヒットします(クエリプランをXMLとして分析してあらゆる種類のスライスとダイシングを実行する必要があるためです)。これを改善するために Github issue#838 を作成し、少なくともユーザーに警告できるようにしましたsys.dm_exec_text_query_planのクエリが大きいかどうかを確認してください。ただし、XML分析を行うことはできません。
おそらく、SSMSからグリッドに返すことができるXMLの最大サイズを調整する必要がありますか?