第13/24周 直方图和密度向量

欢迎回到性能调优培训今天我想详细谈下统计信息在SQL Server内部是如何呈现的。假设有这样的问题:执行计划里的某个运算符的估计行数是42,但你知道对于这个查询,42不是正确的答案。但是你怎么来解读统计信息来理解这个估计是从哪里来的?我们来谈论下直方图(Histogram)和密度向量(Density Vector)。

直方图(Histogram)

首先我们来看下直方图。直方图的用途是用高效、压缩的方式存储列数据分布情况。每次当你在表上创建索引时(聚集/非聚集索引),SQL Server会为你自动创建统计信息。这个统计信息就包含了那列(索引键)的数据分布信息。比如你有一个订单表,里面有个Country列,这列里有很多国家名字。因此直方图就是对这些国家个数分布情况的可视化:

在直方图里,我们用很多柱条描述数据分布情况:柱条越高,那列的这个值就记录数就越多。SQL Server使用同样的概念和格式来描述数据分布情况。我们通过一个例子来详细了解下。在AdventureWorks2008R2数据库里,我们找到表SalesOrderDetail里的ProductID列。这ProductID列存储着具体的销售产品ID信息。可以看到,ProductID列也有索引定义,那就说有对应的统计信息来描述ProductID列的数据分布情况。

在SSMS里,你通过查看表属性来查看列和统计信息,也可以使用DBCC SHOW_STATISTICS命令在结果里输出统计信息。

1  -- Show the statistics for a given index
2 DBCC SHOW_STATISTICS (‘Sales.SalesOrderDetail‘, IX_SalesOrderDetail_ProductID)
3 GO

从上图可以看到,这个命令返回3个不同的记录集:

  • 数据显示标题
  • 密度向量
  • 直方图

如果你想详细了解这部分的统计信息是如何用来做参数预估的,可以看下统计信息内幕:直方图和密度向量

密度向量(Density Vector)

我们再来看看神秘的密度向量,看下非聚集索引IX_SalesOrderDetail_ProductID,这个索引只在ProductID列建立。但是每个非聚集索引,SQL Server在索引的页层也保存聚集键作为逻辑指针。当你定义了非唯一的非聚集索引,聚集键也是非聚集索引导航结构的一部分。表里的聚集键SalesOrderID是个组合列,包含SalesOrderID列和SalesOrderDetailID列。

这就是说我们的非唯一非聚集索引事实上包含ProductIDSalesOrderIDSalesOrderDetailID列。索引键是个组合键。同样SQL Server需要为其他列创建密度向量,因为只有第1列(ProductID)是直方图里有信息,这个在上一部分我们已经看过了。当你看用DBCC SHOW_STATISTICS命令的输出时,密度向量是第2个表信息。

SQL Server在这里存储选择率(selectivity),不同列组合的密度。例如,ProductID列的All density值是0.003759399,你可以用下列语句来验证下:

1  -- The "All Density" value for the column ProductID: 0,0037593984962406015
2 SELECT 1 / CAST(COUNT(DISTINCT ProductID) AS NUMERIC(18, 2)) FROM Sales.SalesOrderDetail
3 GO

对于ProductIDSalesOrderID组合列和ProductIDSalesOrderID,SalesOrderDetailID组合列的All density值分别是8.242868E-06和8.242868E-06。你可以用1除以2个组合列的唯一值来验证下。这里我们的记录是121317,这些聚集值(SalesOrderID,SalesOrderDetailID组成了聚集键)都是唯一的,我们可以计算下:1/121317=8.242867858585359e-6。

在参数预估期间,SQL Server如何使用这个信息,详细可以点击刚才提到的统计信息内幕:直方图和密度向量

小结

今天你看到SQL Server内部是如何构建统计信息的。这里最重要的是直方图(Histogram)密度向量(Density Vector),它们一直是用来做参数预估的。希望这次性能调优培训你有所收获。

你可以阅读下面文章,加深对统计信息的理解:

理解统计信息(1/6):密度向量

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

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

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

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

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

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

下周我们继续讨论在SQL Server里使用参数预估(cardinality estimation)的局限性,还有如何解决它们。到时候见!

时间: 2024-10-07 05:06:18

第13/24周 直方图和密度向量的相关文章

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

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

第13/24周 统计信息

欢迎来到性能调优培训的第4个月.这个月全是关于SQL Server里的统计信息,还有它们如何帮助查询优化器生成足够好的执行计划.统计信息主要是被查询优化器用来估计查询返回的行数.它只是个估计,没别的. 统计信息概述 SQL Server使用在统计信息对象里称作直方图(Histogram)的东西,它描述了对于所给列最大200步长(Steps)的数据分布情况.最大的局限性之一,对于SQL Server里的统计信息是200步长的局限性(使用过滤统计信息可以超过这个步长,这在SQL Server 200

第15/24周 参数预估问题

大家好,欢迎回到性能调优培训.在上2个星期,你已经学过了统计信息,它们为什么重要,还有在SQL Server里它们是什么样的.在这期性能调优培训里我想谈下当前参数预估含有的局限性,还有如何应用不同新技术来克服这些局限. 参数预估错误 上个星期你就看到,当执行计划被编译时,SQL Server使用直方图和密度向量来作参数预估.SQL Server这里使用的模型是个静态的,它有很多的缺点和陷阱.在SQL Server 2014里这些情况会改变——下个星期我会详细讲解这些提升. 为了给你参数预估哪里有

用java写 java1,1,2,4,7,13,24,44算法

//用java写 java1,1,2,4,7,13,24,44算法 ---- 百度知道 import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Result { // 前三个数 private int a = 1, b = 1, c = 2; private List<Integer> list = null; // 构造方法 Result() { list = new 

第24/24周 数据库维护(Database Maintenance)

哇哦,光阴似箭!欢迎回到性能调优培训的最后一期.今天我会详细讲下SQL Server里的数据库维护,尤其是索引维护操作,还有如何进行数据库维护. 索引维护 作为一个DBA,数据库维护是你工作中非常重要的一部分,让数据库获得最佳性能.一个SQL Server数据库就像一辆车:它需要经常的检查来保证运行没有问题,副作用,且拥有最大可能的性能.SQL Server数据库最重要的部分是它的索引及其对应的统计信息对象.SQL Server运行一段时间后会有索引碎片,统计信息必须更新,这样的话查询优化器才可

第10/24周 计划缓存

在这一期的性能调优培训里,我想详细谈下SQL Server里计划缓存及其副作用.在上一周你已经学到,每个提交给SQL Server的逻辑查询会编译成物理执行计划.那个执行计划然后会被缓存,即被称为计划缓存,用作后期的重用.首先我们来看下即席SQL语句(adhoc SQL statements,对应的反义词:prepared SQL statements)的副作用,即带来的性能问题. 即席SQL语句(adhoc SQL statements) 每次当你提交一个即席SQL语句到SQL Server时

源码安装mysql-5.7.13一周的冤枉路总结。满满的都是泪啊

MySQL从5.5以后都是用cmake来进行安装. 5.7.5开始安装环境需要boost库的支持 下载安装包: https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.13.tar.gz https://jaist.dl.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz tar解压安装包. 需要的编译环境:make gcc gcc-c++ ncurses-devel open

第23/24周 临时数据库(TempDb)

在今天的性能调优培训里我们讨论下TempDb——SQL Server的公共厕所,在SQL Server里我是这样描述它的.我们的每个人都会经常使用TempDb.有些人直接使用它,有些人不直接使用它.今天我想给你概括介绍下SQL Server里TempDb的用法,另外我会给你为了更好的性能,如何配置TempDb的一些最佳实践. TempDb用法 我们的每个人使用TempDb.这是我们要接受的事实.因此按需配置TempDb非常重要——即为了获得良好的性能.TempDb存储下列2类对象: 用户对象(U

第11/24周 重编译

今天我想谈下性能调优培训里的重编译(Recompilations ).当你执行一个查询,SQL Server里另一个变动使你执行计划的剩余部分无效,就会发生重编译.在那个情况下SQL Server需要保证你执行计划的准确性,重编译就会被触发.重编译会给你的SQL Server带来额外的CPU开销. 什么是重编译? 首先我想展示下编译和重编译之间的区别.2个星期前,我们讨论了SQL Server里的编译.当查询优化器把提交的查询转化为实际执行计划时,编译就会发生.这就是说编译在查询执行开始前就发生