You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server单查询存1531个执行计划,sp_BlitzCache未检测到该如何排查?

定位SQL Server中存在多执行计划的查询方法

遇到这种情况确实挺头疼的——明明sp_Blitz提示有查询攒了上千个执行计划,但sp_BlitzCache却没揪出来。我分享几个实用的方法帮你定位:

1. 确认计划缓存的时效性

sp_Blitz的提示是基于它执行时的计划缓存状态,但计划缓存可能因为内存压力、手动清理或者SQL Server自动老化机制被清空。建议立刻重新运行sp_Blitz确认那个多计划提示是否还存在,紧接着执行sp_BlitzCache @ExpertMode = 1,避免时间差导致数据不一致。

2. 用系统视图手动查询核心信息

sp_BlitzCache本质也是封装了系统视图,但可能存在过滤逻辑遗漏的情况。直接查询sys.dm_exec_query_stats和sys.dm_exec_sql_text,按query_hash分组(query_hash相同代表逻辑上完全一致的查询),找出计划数异常的查询:

SELECT 
    qs.query_hash,
    COUNT(DISTINCT qs.plan_handle) AS NumberOfPlans,
    -- 提取查询核心片段
    SUBSTRING(st.text, (qs.statement_start_offset/2)+1, 
        ((CASE qs.statement_end_offset 
          WHEN -1 THEN DATALENGTH(st.text) 
          ELSE qs.statement_end_offset 
         END - qs.statement_start_offset)/2)+1) AS QueryText,
    st.text AS FullQueryText
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
GROUP BY qs.query_hash, st.text, qs.statement_start_offset, qs.statement_end_offset
HAVING COUNT(DISTINCT qs.plan_handle) > 1
ORDER BY NumberOfPlans DESC;

这个查询会直接列出所有有多个执行计划的查询,按计划数从高到低排序,很容易定位到那个有1531个计划的目标。

3. 排查参数化设置与临时对象影响

多计划问题大多和参数化有关,先检查数据库的参数化级别:

SELECT name, is_parameterization_forced 
FROM sys.databases 
WHERE name = '你的目标数据库名';

如果是SIMPLE模式,SQL Server只会对简单查询自动参数化,复杂查询可能生成多个计划。另外,如果查询中用到了临时表或表变量,不同会话的临时对象元数据不同,也会导致计划无法共享,这种情况sp_BlitzCache可能不会归类到“多计划查询”里,需要结合上面的系统视图查询结果,检查FullQueryText里是否包含#temp或@table。

4. 直接扫描计划缓存找高频计划

用sys.dm_exec_cached_plans直接统计缓存中相同查询的计划数量,适合定位那些因为文本微小差异(比如空格、大小写)导致的多计划:

SELECT 
    cp.cacheobjtype,
    cp.objtype,
    COUNT(*) AS PlanCount,
    -- 取查询前200个字符作为片段,方便识别
    SUBSTRING(st.text, 1, 200) AS QueryFragment
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
GROUP BY cp.cacheobjtype, cp.objtype, SUBSTRING(st.text, 1, 200)
HAVING COUNT(*) > 100 -- 先筛选计划数超过100的,快速缩小范围
ORDER BY PlanCount DESC;

找到计划数高的QueryFragment后,再结合FullQueryText确认完整查询内容。

5. 调整sp_BlitzCache的参数

试试不带@ExpertMode=1的默认执行sp_BlitzCache,或者增加@TopQueries参数扩大结果范围,比如:

sp_BlitzCache @TopQueries = 2000;

有时候ExpertMode的过滤规则会排除一些边缘情况的多计划查询。

内容的提问来源于stack exchange,提问作者Sicilian-Najdorf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:45:22