如何通过查询从执行计划 xml 中获取已使用索引的列表?
我尝试过以下查询
SELECT DISTINCT
ExecutionPlan.value('(//@Index)[1]', 'NVARCHAR(MAX)') AS UsedIndex
FROM @ExecutionPlan.nodes('//IndexSeek/Object') AS ExecutionPlans(ExecutionPlan)
UNION
-- Find indexes used in IndexScan operations
SELECT DISTINCT
ExecutionPlan.value('(//@Index)[1]', 'NVARCHAR(MAX)') AS UsedIndex
FROM @ExecutionPlan.nodes('//IndexScan/Object') AS ExecutionPlans(ExecutionPlan);
XML 查询计划中有一个命名空间,您在执行查询时需要引用该命名空间。试试这个:
;with xmlnamespaces(default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT DISTINCT
ExecutionPlan.value('(//@Index)[1]', 'NVARCHAR(MAX)') AS UsedIndex
FROM @ExecutionPlan.nodes('//IndexSeek/Object') AS ExecutionPlans(ExecutionPlan)
UNION
-- Find indexes used in IndexScan operations
SELECT DISTINCT
ExecutionPlan.value('(//@Index)[1]', 'NVARCHAR(MAX)') AS UsedIndex
FROM @ExecutionPlan.nodes('//IndexScan/Object') AS ExecutionPlans(ExecutionPlan);
注意,我假设您的查询计划中的 XML 命名空间与我的查询计划中的相同。也许仔细检查您的 XML 并确保它声明的
xmlns
与我提供的 URL 匹配
一个非常简单的解决方案如下 -
DECLARE @ExecutionPlan XML;
SELECT TOP 1
@ExecutionPlan = y.query_plan
FROM sys.dm_exec_query_stats AS x
CROSS APPLY sys.dm_exec_query_plan(x.plan_handle) AS y
ORDER BY x.last_execution_time DESC;
WITH XMLNAMESPACES
(
DEFAULT N'http://schemas.microsoft.com/sqlserver/2004/07/showplan'
)
SELECT DISTINCT
RelOp.typ.value(N'@PhysicalOp', N'varchar(50)') AS operation
, Obj.typ.value(N'@Index', N'varchar(50)') AS index_name
, Obj.typ.value(N'@Table', N'varchar(50)') AS table_name
FROM @ExecutionPlan.nodes(N'//RelOp') RelOp(typ)
CROSS APPLY RelOp.typ.nodes(N'IndexScan') Scan(idx)
CROSS APPLY Scan.idx.nodes(N'Object') Obj(typ)