我在SO上看到过几个响应,其中TSQL语句使用XML数据类型的{.value或.exist方法(here和here)过滤XML数据。虽然我不熟悉这些方法的构造/语法,但我有一个更深层次的问题。
我试图查询一些缓存的执行计划数据,并在数据中搜索特定索引的引用,问题是我不知道XML中的哪个位置。现在我将XML CAST到NVARCHAR并使用LIKE(参见最后一行查询):
DECLARE @IndexName NVARCHAR(100) = 'MyIndex'
SELECT OBJECT_NAME(objectid) AS procname, usecounts, query_plan
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
WHERE objtype = 'Proc'
AND CAST(query_plan AS NVARCHAR(MAX)) LIKE '%' + @IndexName + '%'
所以这有效,但我得到了多余的结果。最后,我想获得索引搜索和扫描的结果,但是现在我还看到了索引被修改的行(例如,一般表更新的执行计划,因为索引也在更新)。
以下是一些简化的示例XML:
<RelOp NodeId="13" PhysicalOp="Index Seek" LogicalOp="Index Seek">
<OutputList>
<ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Employees]" Column="EmployeeID" />
</OutputList>
<IndexScan Ordered="1" ScanDirection="FORWARD">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[MyDB]" Table="[Employees]" Column="EmployeeID" />
</DefinedValue>
</DefinedValues>
<Object Database="[MyDB]" Schema="[dbo]" Table="[Employees]" Index="[MyIndex]" />
</IndexScan>
</RelOp>
答案 0 :(得分:6)
declare @IndexName nvarchar(100) = '[MyIndex]';
with xmlnamespaces (default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
select object_name(qp.objectid),
cp.usecounts,
qp.query_plan
from sys.dm_exec_cached_plans as cp
cross apply sys.dm_exec_query_plan(cp.plan_handle) as qp
where cp.objtype = 'Proc' and
qp.query_plan.exist('//RelOp[
@PhysicalOp = "Index Seek" and
IndexScan/Object/@Index = sql:variable("@IndexName")
]') = 1;
查询计划中的索引具有方括号,因此您需要在变量中包含该索引。
//RelOp
深入搜索选择RelOp
为@PhysicalOp
的所有Index Seek
个节点,并且存在子节点IndexScan/Object
{{1}你存储在变量中的是什么。