Sql server 如何使用TSQL过滤WHERE子句中的XML执行计划数据

Sql server 如何使用TSQL过滤WHERE子句中的XML执行计划数据,sql-server,xml,tsql,sql-execution-plan,Sql Server,Xml,Tsql,Sql Execution Plan,我在这里看到了一些响应,其中TSQL语句使用XML数据类型(and)的.value或.exist方法对XML数据进行过滤。虽然我对这些方法的构造/语法不是很精通,但我有一个更深层次的问题 我试图查询一些缓存的执行计划数据,并在数据中搜索对特定索引的引用,问题是我不知道在XML中查找什么。现在,我将XML转换为NVARCHAR,并使用LIKE(参见查询的最后一行): 这是可行的,但我得到了多余的结果。最后,我希望获得索引查找和扫描的结果,但现在我还看到了索引被修改的行(例如,常规表更新的执行计划,

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

我试图查询一些缓存的执行计划数据,并在数据中搜索对特定索引的引用,问题是我不知道在XML中查找什么。现在,我将XML转换为NVARCHAR,并使用LIKE(参见查询的最后一行):

这是可行的,但我得到了多余的结果。最后,我希望获得索引查找和扫描的结果,但现在我还看到了索引被修改的行(例如,常规表更新的执行计划,因为索引也在更新)

  • 如何重新表述查询的最后一行以使用某种 通配符XML语法(并避免强制转换)
  • 如何优化该查询以仅返回具有 “IndexScan”的父节点
  • 如何优化该查询以仅返回其第一个 发现“RelOp”的祖先具有名为“physicalop”的属性 “索引搜索”的值
  • 下面是一些简化的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>
    
    
    
    声明@IndexName nvarchar(100)='[MyIndex]';
    使用xmlnamespaces(默认值'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
    选择对象名称(qp.objectid),
    cp.usecounts,
    qp.query\u计划
    从sys.dm_exec_缓存_计划作为cp
    交叉应用sys.dm\u exec\u query\u plan(cp.plan\u handle)作为qp
    其中cp.objtype='Proc'和
    qp.query\u plan.exist('//RelOp[
    @PhysicalOp=“索引查找”和
    IndexScan/Object/@Index=sql:variable(“@IndexName”)
    ]') = 1;
    
    查询计划中的索引有方括号,因此您需要在变量中有方括号

    //RelOp
    深入搜索所有
    RelOp
    节点,选择
    @PhysicalOp
    Index Seek
    且存在子节点
    IndexScan/Object
    的节点,其中
    @Index
    是您在变量中存储的内容。

    声明@IndexName nvarchar(100)='MyIndex];
    使用xmlnamespaces(默认值'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
    选择对象名称(qp.objectid),
    cp.usecounts,
    qp.query\u计划
    从sys.dm_exec_缓存_计划作为cp
    交叉应用sys.dm\u exec\u query\u plan(cp.plan\u handle)作为qp
    其中cp.objtype='Proc'和
    qp.query\u plan.exist('//RelOp[
    @PhysicalOp=“索引查找”和
    IndexScan/Object/@Index=sql:variable(“@IndexName”)
    ]') = 1;
    
    查询计划中的索引有方括号,因此您需要在变量中有方括号

    //RelOp
    深入搜索所有
    RelOp
    节点,选择
    @PhysicalOp
    Index Seek
    且存在子节点
    IndexScan/Object
    的节点,其中
    @Index
    是变量中存储的内容

    <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>