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

存储过程在不同数据库执行计划不同,主库无法复现更优执行计划

同存储过程跨库执行计划差异排查方向
  • 排查参数嗅探影响:即使清理过过程缓存,也要确认两个库编译存储过程时传入的@EventId参数对应的数据分布是否一致。生产库首次编译时若传入的是对应大量匹配行的@EventId,优化器会认为Index Scan的顺序IO成本低于Index Seek的随机IO成本,优先选择扫描计划;开发库首次编译若传入小数据量级参数则会生成查找计划。可以在生产库执行存储过程时追加OPTION (RECOMPILE)强制重编译,观察执行计划是否发生变化。
  • 核对统计信息的直方图明细:你提到统计信息接近但不完全相同,需要重点核对Division表EventId列、TeamPlayer表Active列的直方图分段、特定参数值的预估行数差异。即使整体数据量接近,单个参数值的预估行数偏差超过10%就会导致优化器选择不同的访问路径,可以通过DBCC SHOW_STATISTICS('表名','统计信息名称')分别在两个库查询目标参数值对应的预估行数,和实际行数做对比校准。
  • 检查索引物理状态差异:即使索引定义完全一致,生产库高频的写入、删除操作会导致索引碎片率升高、页密度下降,优化器会认为Index Seek的随机IO成本更高,从而优先选择扫描计划。可以通过sys.dm_db_index_physical_stats视图对比两个库相关表上索引的碎片率、平均页密度指标。
  • 核对数据库层面的优化器配置差异:除兼容模式外,还要检查两个库的最大并行度(MAXDOP)、并行执行成本阈值、基数估算器版本、参数嗅探开关是否完全一致,这些配置会直接影响优化器的成本计算逻辑,导致执行计划差异。
  • 临时修复方案:如果无法快速对齐底层差异,可以通过查询存储(Query Store)强制生产库使用更优的Index Seek执行计划,也可以在存储过程的查询末尾添加OPTION (FORCESEEK)查询提示强制走索引查找,修改前需要覆盖所有可能的@EventId参数场景做性能验证。
ALTER PROCEDURE [GetTeamPlayerCount]
    @EventId INT,
    @Active INT = 1
AS
BEGIN
    SET NOCOUNT ON;

    SELECT
        tp.TeamId,
        COUNT(*) AS [Count]
    FROM
        Division d 
    INNER JOIN
        DivisionTeam dt ON dt.DivisionId = d.Id 
    INNER JOIN
        TeamPlayer tp ON dt.Id = tp.TeamId
    WHERE
        d.EventId = @EventId AND tp.Active = @Active
    GROUP BY
        tp.TeamId
    -- 可选添加强制查找提示
    -- OPTION (FORCESEEK)
END

内容的提问来源于stack exchange,提问作者Mike Flynn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:57:03