【问题标题】:Searching for table/index scans搜索表/索引扫描
【发布时间】:2009-10-08 20:23:55
【问题描述】:

是否有人有一个查询可以搜索 SQL2005/2008 的计划缓存,以识别在其执行计划中具有表/索引扫描的查询或存储过程?

【问题讨论】:

    标签: sql-server tsql sql-execution-plan


    【解决方案1】:

    Pinal Dave 实际上对此发表了一篇文章,并对他的原始文章进行了一些修改(几乎不需要任何修改!)您可以获得正确的答案。如果他有帐户,请记下他:)

    http://blog.sqlauthority.com/2009/03/17/sql-server-practical-sql-server-xml-part-one-query-plan-cache-and-cost-of-operations-in-the-cache/

    他的查询是:

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

    获取计划缓存的基本查询并不难,您可以手动 kruft XQuery,但公平地说,Pinal 做了一个很棒的版本,所以我们不要重新发明它。

    【讨论】:

    • 有什么方法可以得到结果集中的过程名?
    • 理论上是的,虽然我必须通过和测试。您不能直接从 XML 查询计划中获取它,因为它不在其中,但查询访问 sys.dm_exec_query_plan,其中包括 objectid 列,该列确实为存储的 proc/functions 提供了一个值,但为 adhoc 查询/批处理提供了一个 null . Left 将其加入到 sys.objects 中,理论上,您拥有 SP 名称。
    • @KM - 发布了一个修改后的版本,如果它可以解决它,则给出过程名称。
    【解决方案2】:

    这需要一段时间才能说服它给我答案,但最终只是一个小改动。如果你想要导致扫描的对象名称,那么它可以完成,但是有问题。

    有一件事限制了它的有效性。 Object_Name / sys.Objects 的范围是您的数据库,因此您可以从任何数据库的缓存中提取所有计划,但只能命名您当前使用的数据库中的计划。

    不保证对象 ID 在数据库之间是唯一的,因此给定的 ID 有可能与您当前的数据库以及另一个数据库匹配,并且您会得到它返回的错误名称,因此无论如何它都不完美.

    同样,如果您看到任何对象 ID > 0 但没有给出名称的内容,则意味着该计划来自一个对象而不是临时查询,但有关该名称的信息位于服务器内不同数据库的系统视图中。

    在单个数据库中的服务器上,它至少是正确的,但它给你的名字是一个指示,而不是福音。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-04
      • 1970-01-01
      • 2011-06-28
      • 2020-01-10
      • 1970-01-01
      • 2012-01-31
      相关资源
      最近更新 更多