惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
宝玉的分享
宝玉的分享
Jina AI
Jina AI
IT之家
IT之家
博客园 - Franky
MyScale Blog
MyScale Blog
Y
Y Combinator Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
雷峰网
雷峰网
WordPress大学
WordPress大学
Microsoft Security Blog
Microsoft Security Blog
Google DeepMind News
Google DeepMind News
美团技术团队
S
SegmentFault 最新的问题
罗磊的独立博客
博客园 - 聂微东
大猫的无限游戏
大猫的无限游戏
H
Help Net Security
D
Docker
博客园 - 司徒正美
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
阮一峰的网络日志
阮一峰的网络日志
M
MIT News - Artificial intelligence

博客园 - Yuejun Sun

Office 365 Certificate Exam Resources How to: Grant Permission on Development Severs as Batch for Windows Authentications Step By Step Guide to configure the “Replicating directory changes” for SharePoint 2010 and 2013 分享:Windows Azure 电子书 Sharepoint 2013配置失败:SQL 实例没有将“MaxDegree of Parallelism”设置为1 免费注册Sharepoint 2013 站点 巧用Discussions列表归档Outlook邮件 Special Offer: Watch Three In-Depth SQL Server Courses by SQLskills (FREE) Forward:Stale statistics on a newly created temporary table in a stored procedure can lead to poor performance How to: Database Service fails to start due to log full of model database 续:有关SQL SERVER分布统计的问题 有关SQL Server分布统计的问题 第三章:分析基本查询的文本和XML执行计划 续第二章:分析基本查询的图形执行计划--表连接 第二章:分析基本查询的图形执行计划 第一章:执行计划基本知识--文本执行计划和XML执行计划 第一章:执行计划基本知识--范例入门 第一章:执行计划基本知识 免费下载:Inside the SQL Server Query Optimizer(查询优化器内幕)
查询优化器如何使用统计—Part I
Yuejun Sun · 2011-10-19 · via 博客园 - Yuejun Sun

原文:http://sqlblog.com/blogs/ben_nevarez/archive/2009/09/03/how-the-query-optimizer-uses-statistics.aspx

备注:翻译不当,请指出或参考原文。

      本文介绍了查询优化器在优化时如何使用统计来估计表达式的选择性,与使用“本地变量”的方式猜测表达式的选择性相比,查询优化器采用探测参数值的方式略显一筹。

      注意:本文并未过多地介绍与之相关主题的其他细节,仅列举出一些简单的示例对查询优化器创建、使用统计进行描述。

       首先启动SQL Server Management Studio并切换到AdventureWorks数据库,运行以下命令显示Sales.SalesOrderDetail表中ProductID列的当前统计信息:

dbcc show_statistics('Sales.SalesOrderDetail', IX_SalesOrderDetail_ProductID)

该命令的输出结果显示了主题、密度及统计对象的histogram。

1)了解histogram

    首先介绍histogram步值的含义,先看步值为86的行,如下所示:

clip_image002

   RANGE_HI_KEY:表示histogram 步的上边界,826是步值为85的上边界,而831是步值为86的上边界,也就是说,步值为86可能只包含从827到831之间的值。

运行下面的查询可以获取ProductID从827到831之间的记录个数:

select ProductID, COUNT(*) as Total 
from Sales.SalesOrderDetail
where ProductID between 827 and 831
group by ProductID

查询结果如下:

image

回到刚才的统计信息处,EQ_ROWS表示估计满足RANGE_HI_KEY值的记录个数,在本例中,RANGE_HI_KEY为831,ProductID为831的记录个数为198条,这与先前输出的统计信息一致。

RANGE_ROWS表示在827和830之间的行数(不包括上边界为831),以本例为例,记录个数包括从827到830之间的,histogram显示出有110条记录满足,通过先前执行的查询统计也可以算出。

DISTINCT_RANGE_ROWS表示在827和830之间不重复的行数(不包括上边界为831),以本例为例,有3个值:827,828,830,故DISTINCT_RANGE_ROWS为3。

AVG_RANGE_ROWS表示由RANGE_ROWS/DISTINCT_RANGE_ROWS计算出,以本例为例,即110/3=36.6667。

接下来,我们看一下统计如何用于估计查询的选择性。

2)查询优化器知道值

     看一下下面的查询:

select * from Sales.SalesOrderDetail 
where ProductID = 831

clip_image006

由于831为步值86的RANGE_HI_KEY,查询优化器使用EQ_ROWS,估计出的行数为198。

现在再运行上面的查询,参数值为828:

select * from Sales.SalesOrderDetail 
where ProductID = 828

clip_image008

这一次,这个值在步值为86的范围内,并且828不是RANGE_HI_KEY,故查询优化器使用AVG_RANGE_ROWS计算的列,其实,查询ProductID为829的记录,估计的行数也是36.6667,即使没有满足829条件的记录也是如此。

下面我们再来看一个不等的运算,试一下找出小于714的行数,也可以通过步值1到7的RANGE_ROWS和EQ_ROWS计算出(13223行)

image

下面看一下在执行计划中显示的估计行数:

select * from Sales.SalesOrderDetail 
where ProductID < 714

image

3)查询优化器对值未知

     这种情况下查询优化器对表达式中的值未知,像使用“本地变量”,由于查询优化器不能使用histogram,因此它会使用包括统计密度信息的其他信息或尝试使用一些固定百分比来猜测选择性,还是通过例子来说明,先看一个“相等”运算:

declare @pid int = 897 
select * from Sales.SalesOrderDetail
where ProductID = @pid

显然在上面的查询中,查询优化器对参数值897未知,由于查询优化器在优化时不知道@pid本地变量的值,故会使用ProductID列的密度值(0.003759399)作来参考,如果用总记录数(121317)乘以密度值(0.003759399),结果为456.079,此值与执行计划中显示的一致。

image
下面,再来看一下“不等”的运算:

declare @pid int = 897 
select * from Sales.SalesOrderDetail
where ProductID < @pid

与先前一样,此处与897无关,使用任何值都将得到相同的估计个数,对于不等运算来说,估计的行数约为总行数的30%,在本例为即为

121317*30%=36395.1。

image