SQL Server慢查询排查:统计信息准确但行数估算错误怎么办
行数估算偏差与内存授予不足排查方向
- 参数嗅探问题:如果查询使用了参数化逻辑或存储过程,可能缓存了小基数DGItemID参数对应的执行计划,后续传入DGItemID=1907这个大基数参数时复用了旧计划,导致行数估算偏低。可对比执行计划中的参数编译值与实际运行值,或添加
OPTION(RECOMPILE)重编译查询,验证估算行数是否恢复正常。 - 隐式类型转换问题:DGItemID使用自定义类型
T_SidDom,若查询传入的参数1907与字段定义类型不匹配,出现类型转换场景时,优化器无法正确匹配统计信息直方图,会引发估算误差。 - 谓词下推受阻:如果查询的JOIN条件、WHERE子句中对
IRItemAnswer_Info的字段使用了函数运算,或和其他表字段做了关联计算,会导致优化器无法直接使用索引统计信息做估算,只能采用默认密度值计算行数,进而出现大幅偏差。 - 自定义域类型统计信息异常:你使用了大量自定义域类型(如
T_SidDom、T_BooleanDom),部分SQL Server版本对自定义类型的统计信息采样、直方图生成存在兼容性问题,即便执行了全量统计信息更新,优化器读取时仍可能出现偏差。可将DGItemID强转为对应基础类型后,核对统计信息中DGItemID=1907对应的行数是否和实际一致。 - 统计信息直方图覆盖不足:如果
IRItemAnswer_Info表的DGItemID去重值超过20000,即便全量更新统计信息,生成的直方图最多也只有200个步长,若1907落在某个步长区间中间,优化器会用步长平均行数做估算,也可能出现偏差。可执行DBCC SHOW_STATISTICS (IRItemAnswer_Info,IRItemAnswerInfo_DGItemID_AnswerBoolean) WITH HISTOGRAM,查看1907对应步长的行数值是否匹配实际数据。 - 行大小估算偏差:内存授予的计算不仅依赖行数,还和每行平均大小有关。即便行数估算准确,如果查询逻辑后续需要读取
AnswerValue这类大字段,优化器对行大小的估算出现偏差,也会导致内存授予不足,触发Hash Match溢出。 - 基数估算器版本问题:如果数据库兼容级别较低,或使用了旧版基数估算器,多JOIN场景下的关联基数计算误差较大。可添加
OPTION(USE HINT('FORCE_DEFAULT_CARDINALITY_ESTIMATION'))执行查询,验证估算结果是否有改善。
内容的提问来源于stack exchange,提问作者Daniel Bragg
相关产品推荐
相关产品推荐

