SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

クエリストアとプランキャッシュの情報の格納単位を比較してみる

leave a comment

クエリストアとプランキャッシュの情報の格納単位が気になったので軽くまとめてみたいと思います。

今回は以下のクエリを実行してみます。

SELECT * FROM sys.objects
WAITFOR DELAY '00:00:05'
SELECT * FROM sys.tables OPTION(RECOMPILE)

 

このクエリですが、一つのバッチと 3 つのステートメントで構成されているクエリとなります。

image

このクエリを実行した後に、以下のクエリでクエリストアとプランキャッシュの情報を確認してみます。

FROM
sys.query_store_query_text qsqt
LEFT JOIN
sys.query_store_query qsq
ON
qsqt.query_text_id = qsq.query_text_id
LEFT JOIN
sys.query_store_plan qsp
ON
qsp.query_id = qsq.query_id
WHERE
query_sql_text LIKE '%sys.objects%' or query_sql_text LIKE '%sys.tables%'
SELECT
SUBSTRING(text,
	([statement_start_offset] / 2) + 1,
	((CASE [statement_end_offset]
	WHEN -1 THEN DATALENGTH(text)
	ELSE [statement_end_offset]
END - [statement_start_offset]) / 2) + 1) AS [stmt_text],
text, query_plan
FROM
sys.dm_exec_query_stats
CROSS APPLY sys.dm_exec_sql_text(sql_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)
WHERE
text LIKE '%sys.objects%' OR text LIKE '%sys.tables%' OPTION (RECOMPILE)

 

実行の結果はこちらに。

image

クエリストアについてはステートメントで情報が格納されています。

プランキャッシュについてもステートメント単位で情報が格納されているのですが、バッチの中でどのステートメントが該当しているかはオフセット情報で管理がされています。

そのため、「sys.objects」を例にした場合の、クエリのプランの情報が以下のように異なっています。

# 上:クエリストア/下:プランキャッシュ

image

image

クエリストアの場合、ステートメント単位で情報を管理しており、クエリのコンパイル時間について、列として簡単に取得することができます。

プランキャッシュについてもステートメントレベルのコンパイル時間は保持しているのですが、単純な列としてではなく、実行プランを開き、該当のステートメントの、「CompileTime」から確認をする必要がありましたので少し手間がかかっていたかと思います。

image

クエリストアでは、格納されている情報がステートメント/実行プラン単位となりますので、実行プランが変わった際のコンパイル時間の変化についてもプランキャッシュから情報を取得するより、簡単に取得できるのは強みになりそうですね。

どのようなケースでクエリストアが効果を発揮するかを考えると奥が深いです。

Share

Written by Masayuki.Ozawa

11月 17th, 2015 at 11:55 pm

Leave a Reply