Jus*_*tin 5 sql-server sql-server-2005 sql-execution-plan
我正在尝试调试一个相当复杂的存储过程,它连接多个tabls(10-11).我看到,对于树的一部分,估计的行数与实际行数大不相同 - 在最差的SQL服务器估计将返回1行,而实际上返回55,000行!
我想弄清楚为什么会这样 - 我的所有统计数据都是最新的,我在几个表上用FULLSCAN更新了统计数据.我没有使用任何用户定义的函数或表变量.据我所知,SQL服务器应该能够准确估计将返回多少行,但它会继续选择一个计划,以便它执行数万次RDI查找(当它只期望执行1次时)或2).
我该怎么做才能尝试理解为什么估计的行数超出这么多?
更新:所以看一下这个计划,我发现了一个特别令人怀疑的节点 - 它使用以下预定表在表上扫描:
status <> 5
AND [type] = 1
OR [type] = 2
Run Code Online (Sandbox Code Playgroud)
这个谓词返回整个表(630行 - 表扫描本身它不是性能不佳的来源)但是SQL服务器的估计行数只有37个.然后SQL服务器继续用RDI做几个嵌套循环查找,索引扫描和索引搜索.这可能是我大量错误计算的根源吗?如何让它估计更合理的行数?
SQL Server
200
使用以下数据将每个索引拆分为最多范围(从此处):
RANGE_HI_KEY
显示直方图步骤上边界的键值.
RANGE_ROWS
指定范围内的行数(它们小于此值
RANGE_HI_KEY
,但大于之前的较小值RANGE_HI_KEY
).
EQ_ROWS
指定完全等于的行数
RANGE_HI_KEY
.
AVG_RANGE_ROWS
范围内每个不同值的平均行数.
DISTINCT_RANGE_ROWS
指定此范围内有多少个不同的键值(不包括之前
RANGE_HI_KEY
和之前的键RANGE_HI_KEY
);
通常,大多数填充值都会进入RANGE_HI_KEY
.
但是,它们可以进入范围,这可能导致分布的偏差.
想象一下这些数据(以及其他数据):
键值行数
1 1
2 1
3 10000
4 1
Run Code Online (Sandbox Code Playgroud)
SQL Server
通常构建两个范围:1
to 3
和4
下一个填充值,这将产生以下统计信息:
RANGE_HI_KEY RANGE_ROWS EQ_ROWS AVG_RANGE_ROWS DISTINCT_RANGE_ROWS
3 2 10000 1 2
Run Code Online (Sandbox Code Playgroud)
,这意味着,当搜索时,2
只有1
行,并且最好使用索引访问.
但如果3
进入范围内,统计数据如下:
RANGE_HI_KEY RANGE_ROWS EQ_ROWS AVG_RANGE_ROWS DISTINCT_RANGE_ROWS
4 10002 1 3334 3
Run Code Online (Sandbox Code Playgroud)
优化器认为3334
密钥有行2
,索引访问太昂贵.
归档时间: |
|
查看次数: |
7567 次 |
最近记录: |