理解统计信息(2/6):直方图

理解统计信息(1/6):密度里,我们讨论了在统计里存储的密度信息。这篇文章会讨论下直方图。我们再次创建SalesOrderDetail表的副本,并在上面建立2个索引。

1 USE StatisticsDB
2 GO
3 SELECT * INTO SalesOrderDetail FROM AdventureWorks2008r2.Sales.SalesOrderDetail
4 CREATE UNIQUE CLUSTERED INDEX ix_SalesOrderDetailID ON SalesOrderDetail(SalesOrderDetailID)
5 CREATE NONCLUSTERED INDEX ix_productid ON SalesOrderDetail(productid)

我们来看看非聚集索引的直方图信息。

1 DBCC SHOW_STATISTICS(‘dbo.SalesOrderDetail‘, ‘ix_productid‘) WITH HISTOGRAM

你会在输出里看到200条记录,上图只显示了前18条记录。为了创建直方图,SQL Server基于索引的第一列值把数据分成不同的桶(步长)。输出结果里每条记录被称为步长。基于数据分布情况,步长的最大个数是200。直方图是你数据的统计表述(statistical representation)。换句话说,它是基于索引的第一列值的数据分布情况。直方图总是基于索引的第一列,即使索引是组合列。这也是为什么建议把经常被选到的列(most selective column)作为索引的第一列的原因,但也有例外。
我们来看直方图的输出结果。它是基于productid值把表里121317条记录分成200个桶(步长)。

RANGE_HI_KEY列表示每桶的上边界值。每桶的下边界值是上一桶的RANGE_HI_KEY+1。对于第一桶,下边界值是生成直方图列的最小值。

RANGE_ROWS列表示在那桶范围内的记录数,但不等于RANGE_HI_KEY值。第一条记录的0值标识,在整个表里没有一条记录productid值是小于707的。我们来看第11条记录,它的RANGE_HI_KEY值是718,RANGE_ROWS 列值是218。这就是说,有218条记录的productid是大于716(上一条RANGE_HI_KEY值)且小于718的。我们可以去验证下。

1 SELECT COUNT(*) FROM SalesOrderDetail WHERE productid>716 AND productid<718

EQ_ROWS列表示表里与RANGE_HI_KEY值匹配的记录数。对于第一条记录,EQ_ROWS值为3083表示表里productid值为707的记录有3083条。我们可以验证下。

1 SELECT COUNT(*) FROM SalesOrderDetail WHERE productid=707

DISTINCT_RANGE_ROWS 列表示在2个RANGE_HI_KEY值之间的不同记录数(不同productid值)。我们来看第11条的RANGE_HI_KEY值是718,DISTINCT_RANGE_ROWS列值为1,这就是说productid值大于716(上一个RANGE_HI_KEY值)且小于718只有1条不同记录。我们可以验证下。

1 SELECT COUNT(distinct productid) FROM SalesOrderDetail WHERE productid>716 AND productid<718

AVG_RANGE_ROWS列表示每个不同值的平均记录数。如果AVG_RANGE_ROWS值大于0的话,和RANGE_ROWS / DISTINCT_RANGE_ROWS相等,不然AVG_RANGE_ROWS的值为1。

SQL Server优化器如何使用直方图来做基数预估(cardinality estimation )呢?我们看下下面查询的执行计划,点击工具栏的显示包含实际的执行计划。

1 SELECT productid FROM SalesOrderDetail WHERE productid>=716 AND productid<=718 

估计行数1513是怎么计算来的呢?我们看下直方图。

红色方框里的数字合计(1076+218+219=1513)就是执行计划里估计行数值。

1076是productid值为716的记录数。

218是productid值大于716且小于718的记录数。

219是productid值等于718的记录数。

三个值的汇总就是上述执行计划里的估计行数。

当where条件复杂时,优化器会创建称为列统计的统计信息,并在直方图数据上使用复合算法(complex algorithm)进行基数预估(cardinality estimation)。我们在下篇文章会谈论这个的更多细节。

时间: 2024-11-01 11:57:03

理解统计信息(2/6):直方图的相关文章

理解统计信息(3/6):谁创建和管理统计信息?在性能调优中,统计信息的作用。

在理解统计信息(2/6):直方图 中,我们讨论了直方图,密度,还有SQL Server如何用统计信息做基数预估(cardinality estimation).这篇文章会讨论统计信息如何被创建,还有统计信息在性能调优中的重要性. 有2类统计信息,索引统计信息和列统计信息.索引统计信息是索引创建的一部分(建立索引会自动创建索引统计信息).在where条件列被引用或查询的group by子句里包含列,列统计信息都会由SQL Server自动创建. 有数据库属性设置里,可以设置数据库是否自动创建统计信

统计信息内幕:直方图和密度向量

有个问题:在执行计划里运算符的估计行数是42,但是你知道查询的正确行数不是42.你也听说了SQL Server使用统计信息来作此估计的?但我们怎么看懂统计信息,来理解这里的估计是怎么来的? 今天我想谈下SQL Server里的统计信息,在直方图(histogram)和密度向量(density vector)里,SQL Server内部是如何保存这些值的并用此来估计行数的. 直方图(Histogram) 首先我们来看下直方图.直方图的用途是用高效.压缩的方式存储列数据分布情况.每次当你在表上创建索

理解统计信息(6/6):统计信息汇总贴

在帮助优化器选择正确的执行计划,统计信息是一个重要因素.因此,我们在处理性能问题时,要足够重视统计信息.可能是对统计信息知识及其相关机制的缺乏,忽略统计信息往往是造成性能问题的根源. 查询优化器在每一步使用统计信息判断返回的行数.在执行计划里的预估行数信息是基于列上的可用统计信息计算而来的.统计信息会给我们列上数据分布信息.没有统计信息,查询优化器不能判断不同计划的效率.通过使用统计信息里的内容,查询优化器在访问数据的时候就可以做出正确选择. 在SQL Server里存储的统计信息包括密度和直方

理解统计信息(4/6):自动更新统计信息的阀值——人为更新统计信息的重要性

在理解统计信息(3/6):谁创建和管理统计信息?在性能调优中,统计信息的作用里我们讨论了统计信息的自动创建和自动更新.我们真的需要人为维护统计信息来保持性能最优?答案是肯定的,这取决与你的工作量.SQL Server只在达到阀限值时进行统计信息的自动更新.当大量的Insert/Update/Delete操作发生时,内建的自动更新统计信息不能持续保证性能的最优. 经过一系列的Insert/Update/Delete后,统计信息可能不会是最新.如果SQL Server查询优化器在表里需要指定列的统计

理解统计信息(5/6):如何检测过期的统计信息

在 理解统计信息(4/6):自动更新统计信息的阀值——人为更新统计信息的重要性 里,我们讨论了自动更新统计信息的阀值,这个阀值在某些情况下,基于自动更新的统计信息还是可以获得最优的执行计划的.在大多数情况下,人为更新统计信息可以获得更好的性能.这个文章,我们可以来看下如何检测过期的统计信息. 在SQL Server 2005以后的版本里,SQL Server使用ColModCtr 对统计的主要列对象进行跟踪.但在 SQL server 2005或SQL server 2008里没有对应的DMV进

理解统计信息(0/6):密度

在日常生活中,我们用统计信息来采取决定.SQL Server优化器也用同样的方式,使用统计信息来选择正确的执行计划.如果统计信息错误或过期,SQL Server可能就会选择错误的执行计划.在这个文章里,我们换个方式理解下统计信息. 查询优化器使用统计信息来判断每一步返回的行.执行计划里的估计行数信息是基于列的可用统计信息计算而来的.统计信息给我们列里数据分布情况.没有统计信息,查询优化器不呢个判断不同计划的效率.通过使用统计信息,查询优化器在访问数据时可以做出正确的选择. 在我们定义索引时,统计

MySQL 8.0 中统计信息直方图的尝试

直方图是表上某个字段在按照一定百分比和规律采样后的数据分布的一种描述,最重要的作用之一就是根据查询条件,预估符合条件的数据量,为sql执行计划的生成提供重要的依据. 在MySQL 8.0之前的版本中,MySQL仅有一个简单的统计信息却没有直方图,没有直方图的统计信息可以说是没有任何意义的. MySQL 8.0新特性之一就是开始支持统计信息的直方图,这个概念很早就提出来了,抽空具体尝试了一下使用方法. 之前写过MSSQL相关统计信息的一点东西,在原理上都是一致的, 照旧,直接上例子,造数据,创建一

Oracle里收集与查看统计信息的方法

Oracle数据库里的统计信息是这样的一组数据:它存储在数据字典里,且从多个维度描述了Oracle数据库里对象的详细信息.CBO会利用这些统计信息来计算目标SQL各种可能的.不同的执行路径的成本,并从中选择一条成本值最小的执行路径来作为目标SQL的执行计划. Oracle数据库里的统计信息可以分为如下6种类型: 表的统计信息 索引的统计信息 列的统计信息 系统统计信息 数据字典统计信息 内部对象统计信息 表的统计信息用于描述Oracle数据库里表的详细信息,它包含了一些典型的维度,如记录数.表块

全废话SQL Server统计信息(2)——统计信息基础

接上文:http://blog.csdn.net/dba_huangzj/article/details/52835958 我想在大地上画满窗子,让全部习惯黑暗的眼睛都习惯光明--顾城<我是一个任性的孩子> 这一节主要介绍一些理论层面的东西,主要针对SQL Server,为后面的做铺垫.假设从实操层面考虑能够跳过,可是我强烈建议还是要找时间看一下这节.本节的内容例如以下: SQL Server统计信息 列级统计信息 统计信息与运行计划 统计信息与内存分配 开销预估模型 SQL Server统计