2009-10-08 113 views

回答

4

皮纳尔戴夫实际上做了一个关于这个帖子,并在他的原始文章(几乎没有任何改动要求!)的一些变化,你可以得到正确的答案。如果他有一个帐户,信用卡他:)

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做了一个很好的版本,因此不让reinv恩。

+0

以任何方式获得结果集中的过程名称? – 2009-10-14 12:55:41

+0

理论上是的,尽管我必须通过并测试。你不能直接从XML查询计划中抓取它,因为它不在那里,但是查询访问sys.dm_exec_query_plan,它包括objectid列,它为存储的proc/functions提供了一个值,但为adhoc查询/批处理提供了一个空值。左加入到sys.objects并理论上,您有SP名称。 – Andrew 2009-10-14 13:45:46

+0

@KM - 发布修改后的版本以提供过程名称,如果它可以解决它。 – Andrew 2009-10-14 14:33:33

2

这花了一段时间来说服它给我的答案,但它是一个小小的变化。如果你想要导致扫描的对象名称,那么它可以完成,但是有问题。

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

对象ID不能保证在数据库之间是唯一的,所以有可能给出的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' 
)