タグ付けされた質問 「plan-cache」

1
キャッシュサイズと予約メモリを計画する
実際の実行計画を含むクエリを実行すると、ルート演算子(SELECT)からキャッシュされた計画サイズが32KBであることが通知されます。 sys.dm_exec_cached_plansとを結合するクエリはsys.dm_os_memory_objects、問題のプランを見て、との値が32768(32KB)であり、キャッシュされたプランのサイズと一致するpages_in_bytesと言いますmax_pages_in_bytes。 私が理解していないのは、の値sys.dm_exec_cached_plans.size_in_bytesが49152(48KB)の略であるということです。これらすべてのコラムでBOLを読みました。特に次のようsize_in_bytesに述べています。 「キャッシュオブジェクトが消費したバイト数。」 それが本当に何を意味するのか理解するために、私はパズルの最後の部分を配置することはできません。 すべての演算子(並べ替えとハッシュに使用される追加のメモリ許可については説明しません)は、キャッシュに最適化されたプランで保存される状態の保存、計算の実行などのために、ある程度の固定メモリを必要としますが、どこにありますか? だから、私の質問は: size_in_bytes本当にどういう意味ですか 「キャッシュされた計画サイズ」よりも高い値になるのはなぜですか? すべての演算子/イテレータのメモリの固定量はどこに予約されていますか、「キャッシュされたプランサイズ」(この例では32Kb)ですか、それとも他の場所ですか? 私はそれらが異なる機能を持つ異なるDMVであることを知っていますが、それらは関連しています。でコンパイルされた(キャッシュされた)計画sys.dm_exec_cached_plans参加するsys.dm_os_memory_objects上でmemory_object_addressのカラム。私がここに質問を投稿する理由は、私がこれについて助けを求めて、DMVとそれらのコラムを解釈する方法を理解しているからです。 場合はsize_in_bytes、なぜSQL Serverは、実際の実行計画で別の値をキャッシュされたプランのサイズと言うんですか? 新しいクエリ、新しい番号: 実際の計画 キャッシュされたプランサイズ16KB CompileMemory 96KB DMV: sys.dm_exec_cached_plans.size_in_bytes 24KB sys.dm_os_memory_objects.pages_in_bytes, .max_pages_in_bytes 16KB。 また、このクエリでは、並べ替えおよびハッシュ操作に追加のメモリ許可が必要ないことに注意してください。 Microsoft SQL Server 2012-11.0.5343.0(X64)

2
SqlCommand.Prepare()を使用する意味と利点は何ですか?
SQLクエリの実行前にSqlCommand.Prepare()(MSDNを参照)メソッドが広く使用されている開発者コードに出会いました。そして、これの利点は何でしょうか? サンプル: command.Prepare(); command.ExecuteNonQuery(); //... command.Parameters[0].Value = 20; command.ExecuteNonQuery(); 私は少し遊んでトレースしました。Prepare()メソッドを呼び出した後にコマンドを実行すると、SQL Serverで次のステートメントが実行されます。 declare @p1 int set @p1=1 exec sp_prepexec @p1 output,N'@id int,@desc text',N'INSERT INTO dbo.testtable (id) VALUES (@id)',@id=20' select @p1 その後、パラメータが値を取得してSqlCommand.ExecuteNonQuery()呼び出されると、次がSql-Serverで実行されます。 exec sp_execute 1,@id=20 私には、これはステートメントがPrepare()実行されるとすぐにコンパイルされるように見えます。これの利点は何でしょうか?これは、それがプランキャッシュに入れられ、目的のパラメーター値で最終クエリが実行されるとすぐに再利用できることを意味しますか? SqlParametersで実行されるSqlCommandsは、常にプロシージャコールでラップされることがわかりました(別の質問で説明しました)sp_executesql。これにより、SQL Serverは、パラメーター値に依存しないプランを保存および再利用できます。 これに関してprepare()は、メソッドが役に立たないのか、時代遅れののか、ここで何かが足りないのでしょうか?

2
ストアドプロシージャの実行計画がない
ストアドプロシージャのキャッシュから計画が欠落する理由は何ですか? 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(何百万行になる可能性がある)、いくつかの更新と削除です。そのため、一時テーブルに多くのデータが変更されます。数百万。

1
クエリプランをステートメントで分割して再利用できるようにした方がよいでしょうか。
クエリによってクエリプランがどのようにコンパイル、格納、および取得されるかについての限られた知識から、複数ステートメントクエリまたはストアドプロシージャがクエリプランを生成し、クエリプランキャッシュに格納されて、今後の実行でクエリによって使用されることを理解しています。 このプランは、クエリハッシュを使用してクエリプランキャッシュから取得されると思います。つまり、クエリを編集して実行すると、ハッシュが異なり、クエリプランキャッシュで一致するハッシュが見つからないため、新しいプランが生成されます。 私の質問は次のとおりです。ユーザーがマルチステートメントクエリのステートメントの1つであるステートメントを実行した場合、マルチステートメントクエリのキャッシュに既にあるクエリプランの関連部分を使用できますか?ハッシュ値が明らかに一致しないため、答えはノーだと思いますが、マルチステートメントクエリの各ステートメントをハッシュして、クエリから個々のステートメントを実行しているユーザーが使用できるようにした方がよいでしょうか? 私は考慮していない複雑な問題があると思います(そして、私が本当に知りたいのはこれらです)が、より多くのスペースを使用し、さらに多くのクエリプランに同じ「ステートメントプラン」を格納することができるようです生成するCPUと時間。 私の無知を示​​しているだけかもしれません。

1
SQLHANDLEの無限再コンパイルの可能性が検出されました
私はSQLエラーログで奇妙なエラーメッセージを見つけてきました: Bocss:1時間ごとに同じデッドロックが発生–調査が必要 また、次の例のように、他のSPIDのエラーログに多くの再コンパイルがリストされます。 2015年9月4日14:30:10、spid64、Unknown、SQLHANDLE 0x0200000059631A288882589E0C54B76404CAE1B97E08D3680000000000000000000000000000000000000000 PlanHandle 0x0600040059631A2860A62B654100000001000000000000000000000000000000000000000000000000000000開始オフセット600200000010000000000000000000000000000000000000000000000000000000開始オフセット600200000010000000000000000000000000000000000000000000000000000000開始オフセット600200000010000000000000000000000000000000000000000000000000000000開始オフセット600400000009000000 、spid150、Unknown、SQLHANDLE 0x02000000EF886F018C4E0B163812B8B20150FE8FC7E6A06A0000000000000000000000000000000000000000 PlanHandle 0x06000400EF886F01901A816E0600000001000000000000000000000000000000000000000000000000000000開始オフセット998、最後のオフセット252015終了オフセット2.9 09終了オフセット25209 09終了オフセット25209 09終了オフセット2509 0930:09、spid163、不明、可能無限の再コンパイルがSQLHANDLE 0x02000000E7C7BF0E5D70DE55759C7842860272AD474D69AB0000000000000000000000000000000000000000 PlanHandle検出された可能無限の再コンパイルは、最後の再コンパイルの理由2. 2015年9月4日14れた2652終了オフセット1064オフセット開始SQLHANDLE 0x0200000057C4C632D9052275CFF2B683B80F29501EE91D730000000000000000000000000000000000000000 PlanHandle 0x0600040057C4C63200EAC2BE3000000001000000000000000000000000000000000000000000000000000000検出されました0x06000400E7C7BF0EF0EB68A52C00000001000000000000000000000000000000000000000000000000000000開始オフセット1028終了オフセット2580。最後の再コンパイル理由は2でした。 何が原因でしょうか? キャッシュにプランがもうないようです。 この投稿のアドバイスに従って http://www.sqlservercentral.com/Forums/Topic1479420-146-1.aspx 次に、安全対策によりフルテキストカタログが無効にされたため、これには違いがなかったため、変更を完全にロールバックしました(新しいオブジェクトをドロップしたなど)。これでも違いはありませんでした。結局、SQLインスタンスの再起動がそれを止めるように見えた唯一の事柄であり、これが問題を即座に解決しました。 これも私を整理しました、しかし、私はまだ最初にこの混乱を引き起こした原因を見つける必要がありますか?

1
測定プランの削除
最大メモリが24GBに設定されたSQL Server 2016 SP1があります。 このサーバーには多数のコンパイルがあり、これらのコンパイルの10%のみがアドホッククエリからのものです。したがって、新しくコンパイルされたプランはプランキャッシュに保存されますが、プランキャッシュのサイズは増加していません(約3.72GB)。 キャッシュからのプランの削除につながるローカルメモリのプレッシャーがあると思います。プランのキャッシュ圧力制限は5GBです。(0-4GBの可視ターゲットメモリの75%+ 4GB-64GBの可視ターゲットメモリの10%+可視ターゲットメモリの5%> 64GB)。キャッシュストアが圧力制限の75%に達したら、プランをキャッシュから削除する必要があります。私の場合、5 GBの75%は3.75GBです。したがって、これが高コンパイルの原因であると考えられます。 キャッシュからの計画からの削除を測定する方法(perfmon、拡張イベントなど)はありますか?だから私は確かにローカルメモリのプレッシャーが高コンパイルの原因であることを確信できますか?


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.