SQL Server查询计划缓存和编程检索

时间:2013-09-26 14:22:07

标签: c# sql sql-server

我有一个运行SQL查询的.NET客户端应用程序,该查询偶尔会被ADO.NET超时。当它超时时,我看不到在dm_exec_query_stats中缓存查询计划。如果查询完成,则计划 缓存。

在我的应用程序异常处理程序中,我想以编程方式捕获超时的特定类查询的查询计划 - 这将帮助我进行故障排除。这可能吗?由于每个可能的超时查询引用具有唯一名称的表,因此我可以扫描查询文本以查找适当的计划。

我希望在我的异常处理程序中能够运行:

SELECT TOP 1 p.query_plan, t.text
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text (qs.plan_handle) AS t
CROSS APPLY sys.dm_exec_query_plan (qs.plan_handle) AS p
WHERE t.text LIKE '%UNIQUETABLE%'
ORDER BY last_execution_time DESC;

但是这不包含我正在寻找的查询 - 可能是因为它超时了?

是否可以检索用于启动随后被中止的查询的查询计划?

(正在执行的SQL是动态的;使用存储过程可以更轻松地生活,但遗憾的是它不可用!)

2 个答案:

答案 0 :(得分:1)

您的数据库是否可能针对临时工作负载进行了优化?

sp_CONFIGURE 'optimize for ad hoc workloads'

答案 1 :(得分:1)

这将为您提供查询计划:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <GetOpenOrdersResponse xmlns="http://tempuri.org/">
            <GetOpenOrdersResult xmlns:a="http://schemas.datacontract.org/2004/07/FazioAPISoap" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <a:OrderSummary>
                    <a:order_header_data>
                        <a:Bar>false</a:Bar>
                        <a:Foo>Things</a:Foo>
                    </a:order_header_data>
                    <a:order_id>10001</a:order_id>
                </a:OrderSummary>
                
            </GetOpenOrdersResult>
        </GetOpenOrdersResponse>
    </s:Body>
</s:Envelope>

在这里,您可以列出那些超时的人:

SELECT cplan.usecounts, 
       cplan.objtype, 
       qtext.text, 
       qplan.query_plan
FROM sys.dm_exec_cached_plans AS cplan
     CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS qtext
     CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS qplan
     WHERE qtext.text LIKE '%UniqueName%'
ORDER BY cplan.usecounts DESC;