在sqlserver中,优化器如何利用统计信息来估算返回的行数(一)

先来看一幅图:

image

优化器是根据统计信息来生成执行计划的,具体来说是根据物理操作符(physical operator)预估返回的行数来生成执行计划的,

优化器预先是不知道真实数据分布情况的,所以统计信息准确与否直接决定了执行计划的优劣

先来看过滤条件为一个字段是如何评估返回的行数?

use AdventureWorks
go
 
create index idx_postTime on 
dbo.DataBaseLog(posttime) with(online=on)
 
select * from dbo.DatabaseLog 
where PostTime='2006-04-26 11:44:30.217'
OPTION
(
    QUERYTRACEON 3604,
    QUERYTRACEON 9292,
    QUERYTRACEON 9204
)

option() 使用来查看生成执行计划过程中,优化器加载了那些统计信息:

image

可以看到使用到了indexid=3的统计信息,那对应的统计信息名是什么呢?使用如下的脚步可以看到:

use AdventureWorks
go
 
select object_name(s.object_id) as tbname,
    s.name as stastistics_name,
    COL_NAME(s.object_id,c.column_id) as stats_column,
    s.stats_id ,
    i.rowcnt,
    i.rowmodctr,
    stats_date(s.object_id,s.stats_id) as updated_time
from sys.sysindexes as i
inner join sys.stats as s
on i.id=s.object_id
and i.indid=s.stats_id
inner join sys.stats_columns c
on c.object_id=s.object_id
and c.stats_id=s.stats_id
where i.id in(object_id('DatabaseLog'))

结果是:

image

即为刚新建的索引所对应的统计信息。需要说明的是,对于手动新建的索引,其index_id是为统计信息的stats_id

再来看看该列上的 直方图:

DBCC show_statistics(DatabaseLog,idx_postTime)

 

image

 

EQ_ROWS=1,所以执行计划中预估的返回行数为1,如下图所示:

 

image

 

Actual Number of Rows = Estimated Number of Rows,所以生成的是最优的执行计划

总结:对于相等性的过滤条件,且没有使用到参数,如 [where PostTime='2006-04-26 11:44:30.217']

优化器是直接使用直方图来评估返回的行数!

原文地址:https://www.cnblogs.com/fly_zj/p/3034382.html