SQL2005/2008 のプラン キャッシュを検索して、実行プラン内にテーブル/インデックス スキャンがあるクエリまたはストアド プロシージャを特定するクエリを持っている人はいますか?
2 に答える
Pinal Daveは実際にこれについて投稿し、彼の元の記事に少し変更を加えることで(ほとんど変更は必要ありません!)、正しい答えを得ることができます。彼がアカウントを持っている場合は、彼にクレジットを付けてください:)
彼の質問は次のとおりです。
WITH XMLNAMESPACES(DEFAULT N'http://schemas.microsoft.com/sqlserver/2004/07/showplan'),
CachedPlans
(
ParentOperationID,
OperationID,
PhysicalOperator,
LogicalOperator,
EstimatedCost,
EstimatedIO,
EstimatedCPU,
EstimatedRows,
PlanHandle,
QueryText,
QueryPlan,
CacheObjectType,
ObjectType)
AS
(
SELECT
RelOp.op.value(N'../../@NodeId', N'int') AS ParentOperationID,
RelOp.op.value(N'@NodeId', N'int') AS OperationID,
RelOp.op.value(N'@PhysicalOp', N'varchar(50)') AS PhysicalOperator,
RelOp.op.value(N'@LogicalOp', N'varchar(50)') AS LogicalOperator,
RelOp.op.value(N'@EstimatedTotalSubtreeCost ', N'float') AS EstimatedCost,
RelOp.op.value(N'@EstimateIO', N'float') AS EstimatedIO,
RelOp.op.value(N'@EstimateCPU', N'float') AS EstimatedCPU,
RelOp.op.value(N'@EstimateRows', N'float') AS EstimatedRows,
cp.plan_handle AS PlanHandle,
st.TEXT AS QueryText,
qp.query_plan AS QueryPlan,
cp.cacheobjtype AS CacheObjectType,
cp.objtype AS ObjectType
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
CROSS APPLY qp.query_plan.nodes(N'//RelOp') RelOp (op)
)
SELECT
PlanHandle,
ParentOperationID,
OperationID,
PhysicalOperator,
LogicalOperator,
QueryText,
CacheObjectType,
ObjectType,
EstimatedCost,
EstimatedIO,
EstimatedCPU,
EstimatedRows
FROM CachedPlans
WHERE CacheObjectType = N'Compiled Plan'
そして最後に必要なのは、具体的にはスキャンタイプ(クラスター化、テーブル、インデックス)です。
and
(PhysicalOperator = 'Clustered Index Scan' or PhysicalOperator = 'Table Scan'
or PhysicalOperator = 'Index Scan')
プランキャッシュを取得するための基本的なクエリは難しくありません。XQueryを手動で作成できますが、公平を期すために、Pinalはその優れたバージョンを実行したため、再発明することはできません。
それが私に答えを与えるように説得するのにしばらく時間がかかりましたが、最終的には小さな変更です. スキャンの原因となっているオブジェクト名が必要な場合は実行できますが、問題があります。
その効果を制限していることが 1 つあります。Object_Name / sys.Objects のスコープはデータベースにあるため、任意のデータベースのキャッシュからすべてのプランを取得しますが、現在使用しているデータベース内にあるプランにのみ名前を付けることができます。
オブジェクト ID はデータベース間で一意であることが保証されていないため、指定された ID が現在のデータベースや別のデータベースと一致する可能性があり、間違った名前が返される可能性があるため、決して完全ではありません。
同様に、オブジェクト ID が 0 より大きいものの名前が指定されていない場合は、プランがアドホック クエリではなくオブジェクトからのものであり、その名前に関する情報がサーバー内の別のデータベースのシステム ビューにあることを意味します。
単一のDB内のサーバーでは、少なくとも正しいですが、福音ではなく、指示として与えられた名前を使用してください。
WITH XMLNAMESPACES
(DEFAULT N'http://schemas.microsoft.com/sqlserver/2004/07/showplan'),
CachedPlans
(
ParentOperationID,
OperationID,
PhysicalOperator,
LogicalOperator,
EstimatedCost,
EstimatedIO,
EstimatedCPU,
EstimatedRows,
PlanHandle,
QueryText,
QueryPlan,
CacheObjectType,
ObjectType,
ObjectID)
AS
(
SELECT
RelOp.op.value(N'../../@NodeId', N'int') AS ParentOperationID,
RelOp.op.value(N'@NodeId', N'int') AS OperationID,
RelOp.op.value(N'@PhysicalOp', N'varchar(50)') AS PhysicalOperator,
RelOp.op.value(N'@LogicalOp', N'varchar(50)') AS LogicalOperator,
RelOp.op.value(N'@EstimatedTotalSubtreeCost ', N'float') AS EstimatedCost,
RelOp.op.value(N'@EstimateIO', N'float') AS EstimatedIO,
RelOp.op.value(N'@EstimateCPU', N'float') AS EstimatedCPU,
RelOp.op.value(N'@EstimateRows', N'float') AS EstimatedRows,
cp.plan_handle AS PlanHandle,
st.TEXT AS QueryText,
qp.query_plan AS QueryPlan,
cp.cacheobjtype AS CacheObjectType,
cp.objtype AS ObjectType,
qp.objectid
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
CROSS APPLY qp.query_plan.nodes(N'//RelOp') RelOp (op)
)
SELECT
PlanHandle,
ParentOperationID,
OperationID,
PhysicalOperator,
LogicalOperator,
QueryText,
CacheObjectType,
ObjectType,
EstimatedCost,
EstimatedIO,
EstimatedCPU,
EstimatedRows,
QueryPlan,
C.ObjectID,
Object_Name(C.ObjectID)
FROM CachedPlans C
Where
(PhysicalOperator = 'Clustered Index Scan'
or
PhysicalOperator = 'Table Scan'
or
PhysicalOperator = 'Index Scan'
)