EXECステートメントのquery_hashがゼロになるのはなぜですか?


8

私は、拡張イベントを使用してSQL Serverの監視システムをセットアップし、開発者向けの「運用フィードバック」として重いクエリを見つけています。私は、イベントを使用していますsp_statement_completedsql_statement_completed、CPU_TIME上の述語フィルタを使用して、論理読み取り、など私は上の結果集計するために期待していたdatabase_nameし、query_hashすべてのインターネット上で多数の例で示されたように、結果に、私はそれが見るquery_hashすべての文のために0であります以下の表のように、EXECを使用します(読みやすくするためにタイムスタンプとクエリハッシュを短縮)。

name                       timestamp      query_hash plan_handle        statement
sql_statement_completed    2016...6414    0          050056019600764... exec Shared.dbo.SyncFirm  
sql_statement_completed    2016...9946    0          06003d00e01e730... exec spSetUserAuth @userid;  
sql_statement_completed    2016...7184    0          0600e30028c9da0... exec spSetUserAuth @userid;  
sp_statement_completed     2016...0409    9826...578 0600c00028e6aa0... SELECT obfuscated_columns FROM dbo.SomeTable
sp_statement_completed     2016...1448    8660...775 060084006d2d660... INSERT INTO dbo.SomeTable ( obfuscated_columns)  EXEC(@sql)
sql_statement_completed    2016...7752    0          0600f9006c23f03... exec spSetUserAuth @userid;  
sql_statement_completed    2016...1443    1304...641 06005a0008a9b11... select SUBQ.ontrackstatus, COUNT(SUBQ.ontrac

すべての結果には価値がplan_handleあり、それらはすべて異なるため、多くの計画が生成されています。query_hash(私が見た)を含まない他のステートメントには、ALTER INDEX、CHECKPOINT、UPDATE STATISTICS、COMMIT TRANSACTION、FETCH NEXT FROM Cursor、一部のINSERT、SELECT @ variable、IF(@variable = x)があります。

query_hashが0である理由を誰かが知っていますか?SQLクエリアナライザーとEXECのどこかにポイントがないと思いますが、正しい方向に向ける手掛かりを見つけることができません。私が持っている結果が「正常」である場合、結果を最もよく集計するにはどうすればよいですか?ステートメントによるグループ化には、query_hashの計算時に削除されるリテラル、空白などが含まれませんか?

編集:私が今見ているようにEXEC SomeStoredProcedure、ストアドプロシージャ(自明)を開始し、そのストアドプロシージャ内の個々のステートメントはイベントとしてイベントセッションで終了し、sp_statement_completedそれらすべてにquery_hashがあります。

したがってsp_statement_completed(つまり、「実際の」クエリ)、query_hashとdatabase_nameで集計できますsql_statement_completed。query_hash(EXEC SomeStoredProcedure)なしでは、を使用しclient_connection_idて、ストアドプロシージャの特定の実行内のステートメントをグループ化し、最も多いものを確認できます。手順の費用のかかる部分。


2
私はなぜ知らないquery_hash0ですが、なぜ用としてexec spSetUserAuth @userid;行は別のプランハンドルを持っている:The algorithms to match new SQL statements to existing, unused execution plans in the cache require that all object references be fully qualified.出典。)これらすべてのエントリが例えばだったらexec dbo.spSetUserAuth @userid;、あなたは彼らのために、同一のプランハンドルを取得する可能性があります。
Andriy M

それらは異なるデータベースで使用されているため、異なるplan_handlesを持っています。その場合、オブジェクト参照は同じではないため、プランが異なります。ご指摘ありがとうございます。
Bert Van Landeghem、2016年

もしそうならそれはあなたの問題を解決しないでしょうか?データベースごとのアクティビティに関するレポートを生成でき、特定の手順でパラメータのスニッフィング/パラメータ化の問題を検出できます。
トムV-topanswers.xyzを試してください。16年

ええ、実際には...
バートヴァンランデゲム

3
根本的な問題が実際に解決された場合、結果を説明する回答を投稿して、それが問題の解決にどのように役立ちましたか?必ずしもそうする必要はありませんが、何らかの方法で刺激を受けることができれば、それはこのサイトのナレッジベースへの貴重な貢献となるでしょう。質問/回答を明確にするのに役立つ限りコメントを残しておくことをお勧めします。後で安全に削除できるように、これらのコメントですでに言及されているポイントを自由に繰り返してください。
Andriy M

回答:


1

ハッシュが作成される理由を説明するには:

サーバーにクエリを送信すると、algebrizer(はい、それが呼び出されます)プロセスは、コード化された署名のように、クエリのハッシュを作成します。ハッシュは一意の識別子です。識別子は、スペースやキャリッジリターンなど、クエリを定義するすべてのテキストを含め、特定のクエリに対して一意であり、オプティマイザはハッシュをキャッシュ内のクエリと比較します。エンジンに入ってくるクエリと一致するクエリがキャッシュに存在する場合、最適化プロセスのコスト全体がスキップされ、プランキャッシュ内の実行プランが再利用されます。

EXECEXECSQL Serverは、最適化のために比較する必要がないことを認識しているため、コードを変更できるストアドプロシージャを開始します。SQLServerはハッシュを作成しません。

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