1

我在这里看到了一些关于 SO 的响应,其中 TSQL 语句使用 XML 数据类型的 .value 或 .exist 方法过滤 XML 数据(此处此处)。虽然我不精通这些方法的构造/语法,但我有一个更深层次的问题。

我正在尝试查询一些缓存的执行计划数据并在数据中搜索对特定索引的引用,问题是我不知道在 XML 中查找的位置。现在我将 XML 转换为 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 + '%'

所以这行得通,但我得到了多余的结果。最终,我想获得索引搜索和扫描的结果,但现在我还看到了索引被修改的行(例如,一般表更新的执行计划,因为索引也在更新)。

  1. 如何改写查询的最后一行以使用某种通配符 XML 语法(并避免 CAST)?
  2. 如何优化该查询以仅返回具有“IndexScan”父节点的项目
  3. 如何优化该查询以仅返回“RelOp”的第一个找到的祖先具有名为“PhysicialOp”且值为“Index Seek”的属性的那些项目?

下面是一些简化的 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>
4

1 回答 1

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,该子节点@Index是您存储在变量中的内容。

于 2013-07-10T14:15:48.997 回答