現在、クエリを実行しているデータベースに対して99%のアドホッククエリプランを生成していると思われるアプリケーションを調査しています。これを確認するには、次のステートメントを実行して、クエリプランキャッシュ内のオブジェクトの概要を取得します。
SEエディターにコードを入力できなかったため、スクリーンショット
参照:キャッシュの計画とアドホックワークロードの最適化 (SQLSkills.com/K. Tripp)若干の修正あり
上記のクエリの結果は次のとおりです。
CacheType Total Plans Total MBs Avg Use Count Total MBs - USE Count 1 Total Plans - USE Count 1
-------------------- -------------------- --------------------------------------- ------------- --------------------------------------- -------------------------
Adhoc 158997 5749.520042 2 2936.355979 126087
Prepared 1028 97.875000 695 46.187500 576
Proc 90 69.523437 39659 21.187500 21
View 522 75.921875 99 0.453125 3
Rule 4 0.093750 22 0.000000 0
Trigger 1 0.070312 12 0.000000 0
プランキャッシュの158'997アドホッククエリのうち、126'087クエリは1回しか実行されていません。
アドホッククエリをさらに調べたところ、一部のクエリが複数回生成されることさえありました。次のクエリを使用してプランキャッシュを調べ、同一の実行プランを取得しました。
SELECT SUM(cplan.usecounts) AS [Unique Same Single Plans],
qtext.text
FROM sys.dm_exec_cached_plans AS cplan
CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS qtext
CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS qplan
JOIN sys.databases AS sdb
ON sdb.database_id = qplan.dbid
WHERE 1 = 1
AND cplan.objtype = 'Adhoc' -- <-- only Adhoc plans
AND sdb.name = 'DATABASENAME' -- <-- for a certain database
AND cplan.usecounts = 1 -- <-- with a usecounts of 1
GROUP BY
qtext.text having sum(cplan.usecounts) > 1
ORDER BY
1 DESC --,cplan.objtype, cplan.usecounts
参照:覚えていない。それが元々あなたのものだったかどうか教えてください。私がそれを認めます。
これにより、既存の同一のクエリプランと同一のクエリプランと、の一意の同一のクエリプランの合計を持つアドホッククエリのリストが表示されます。計画キャッシュ。
編集されたGUIDからわかるように、複数回作成された多くの一意のアドホッククエリプランがあります。
私が正しい方向に進んでいることを証明するために、一意のカウントが3である上からステートメントを取得し、そのステートメントをフィルターとしてプランキャッシュサマリーステートメントで使用して、ステートメントとクエリプランを取得しました。
SELECT cplan.usecounts,
qtext.text,
qplan.query_plan
FROM sys.dm_exec_cached_plans AS cplan
CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS qtext
CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS qplan
JOIN sys.databases AS sdb
ON sdb.database_id = qplan.dbid
WHERE 1 = 1
AND cplan.objtype = 'Adhoc'
AND sdb.name = 'DATABASENAME'
AND qtext.text =
'SELECT description,id,name,osguid,profil FROM omitted WHERE osguid IN (SELECT osgroupguid FROM omitted WHERE osuserguid=''81C4B8_REMOVED_SOME_9DD2'')'
ORDER BY
1 DESC
参照:覚えていない。それが元々あなたのものだったかどうか教えてください。私がそれを認めます。
これにより、作成されてプランキャッシュに保存された一意のアドホッククエリのリストが表示されます。
上記のスクリーンショットの数値は、カウントが3であるため、1つのクエリが既に再利用されていることを示しています。ただし、すべてのクエリは同じです。
ここまで読んだことから、私は次のことを前提としています。
Adhoc
エントリが作成されます私は同様に次のことを認識しています。
optimize for ad hoc workloads
をオンにすると、1回だけ使用されるアドホックプランのキャッシュ内のクエリプランのサイズがわずかに減少しますALTER DATABASE [DATABASENAME] SET PARAMETERIZATION FORCED
を実行するのは良い考えですが、それは... この質問の入力中にポップアップしたすべての記事といくつかの関連する質問を読んだ後、次の2つの質問があります。
パラメータ化されていないクエリプランは一意であると見なされているため、私の質問が矛盾していることに気づきましたが、なぜ一部のパラメータ化されていないアドホッククエリプランが再利用されるのですか?
「同一の」クエリの計画をXML形式で保存し、ファイルを比較します。(たとえば、設定されたオプションで)いくつかの違いがある可能性があると思います– Denis Rubashkin 29分前
SETオプションは同じです。計画全体の唯一の違いは、CompileTime
とCompileCPU
の<StatementSetOptions>
セクションの後の2行目にあります。以下の両方の関連部分を貼り付けました:
<StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="false" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false" />
<QueryPlan CachedPlanSize="32" CompileTime="4" CompileCPU="4" CompileMemory="472">
<StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="false" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false" />
<QueryPlan CachedPlanSize="32" CompileTime="3" CompileCPU="3" CompileMemory="472">
その他の違いは見つかりませんでした。
この質問のキュレーションに使用された参考資料:
アドホックワークロードの最適化をオンにすると、キャッシュ内のクエリプランのサイズがわずかに減少します
...
プランキャッシュの158'997アドホッククエリのうち、126'087は1回しか実行されていません。
アドホック計画の79%を削除することはわずか削減とは呼びません。
パラメータ化されていない、自明ではないアドホッククエリプランが再利用されるのはどの場合ですか?
同じデータベースに接続しているクライアントがプランをキャッシュに入れた後、まったく同じクエリを同じセッション設定で実行します。
そう、
同一のステートメントに対して複数のキャッシュされたクエリプランがあるのはなぜですか?
通常は、クエリの動作に影響を与えるさまざまな設定のセッションです。空白を含むクエリ内のテキストの違いは、これを引き起こす可能性があります。オブジェクトの名前解決が異なるため、ユーザーのデフォルトのスキーマがこれを引き起こす可能性があります。また、ほぼ同時に送信された2つの同一のクエリは、個別に最適化されてキャッシュされる場合があります。