我想问一下SQL Server如何估计下面的查询中的那些行,如果它使用直方图来计算估计行,它是如何做的。任何提示或链接的答案是非常感谢。用SQL Server统计直方图估计范围谓词
use AdventureWorks2012
go
select *
from sales.SalesOrderDetail
where SalesOrderID between 43792 and 44000
option (recompile)
我想问一下SQL Server如何估计下面的查询中的那些行,如果它使用直方图来计算估计行,它是如何做的。任何提示或链接的答案是非常感谢。用SQL Server统计直方图估计范围谓词
use AdventureWorks2012
go
select *
from sales.SalesOrderDetail
where SalesOrderID between 43792 and 44000
option (recompile)
SQLSERVER构造柱的统计数据基于该直方图可以得出:分析该列中的数据分布和估计
让举一个小例子来理解数据更多..
drop table t1
create table t1
(
id int
)
insert into t1
select top 300 row_number() over(order by t1.number) as N
from master..spt_values t1
cross join master..spt_values t2
go 3
select * from t1 where id=1
dbcc show_statistics('t1','_WA_Sys_00000001_29572725')
DBCC给我下面historgram
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1 0 3 0 1
3 3 3 1 3
4 0 3 0 1
6 3 3 1 3
8 3 3 1 3
10 3 3 1 3
以上是DBCC的剪断output.Before跳进解释什么是那些mean.Lets了解数据是如何分布在表
有1 300行300,重复3 times.So行的总数是900
现在让我们了解这些列的含义
RANGE_HI_KEY:
SQL服务器在本列中使用的值作为键顶部构建直方图,由于直方图仅限于200 steps..It选择用于构建直方图..this 行会被限制在200 steps.in这种情况下的值是1,3,4,6等
RANGE_ROWS:
此数字表示步骤内的是比以前的顶部密钥和当前键顶更高的行数,但不等于两者。
行> 1和< 3等
EQ_ROWS:
指定有多少行是完全相同equa1到。在这种情况下最高值,这是= 1,3等等
DISTINCT_RANGE_ROWS:
这些是一个步骤内的行的重复计数。如果所有行都是唯一的,则RANGE_ROWS和DISTINCT_RANGE_ROWS将相等。
不同行,其中值> 1和< 3等
AVG_RANGE_ROWS:
这代表行等于所述步骤中的关键值,这意味着行的平均数量的平均数等于顶级键即。,1,3等
**一些演示查询**
select * from id=1
我们知道EQ_ROWS 1具有值3,所以你可以看到的估计行的3
这是对于简单的等于查询,但它是如何为多个谓词像一个工作你的情况..
巴特邓肯提供了一些见解
优化程序有多种估算基数的方法,其中没有一种是完全万无一失的。
如果谓词很简单,如“column = 123”,并且搜索值恰好是直方图端点(RANGE_HI_KEY),则EQ_ROWS可用于非常准确的估计。
如果搜索值碰巧落在两个步骤端点之间,那么该特定直方图步骤中的值的平均密度用于估计谓词选择性和操作符基数。
如果在编译时未知道特定的搜索值,则下一个最佳选项是使用平均列密度(“所有密度”),该平均列密度可用于计算将与平均值匹配的行数该列。
在某些情况下,以上都不可能,优化器不得不求助于基于“幻数”的估计。例如,可能会完全猜测10%的行将被返回,其中“10%”值将在优化器代码中硬编码,而不是从统计信息派生。
进一步参考和阅读:
https://sqlperformance.com/2014/01/sql-plan/cardinality-estimation-for-multiple-predicates
https://blogs.msdn.microsoft.com/bartd/2011/01/25/query-tuning-fundamentals-density-predicates-selectivity-and-cardinality/
感谢您的支持,您的答案是不是真正的我所期待的,但是从你的提示,我能猜出自己。实际上,我的问题还不够清楚,真正的问题是谓词落在两步之间(两个RANGE_HI_KEY值)如何计算估计的行数?查询看起来像 select * from sales.SalesOrderDetail where SalesOrderID <43660 我说“猜”,因为我没有找到任何文章谈这件事,但我发现SQL Server可能会使用插值方法做? ? – Lukas85
如果我们无法确切知道SQL Server使用哪个公式? – Lukas85