前言html
通过前几篇的分析,其实大致已经初窥到SQL Server统计信息的重要性了,因此本篇就要祭出这个神器了。数据库
该篇内容会很长,坐好板凳,瓜子零食之类...并发
不废话,进正题post
技术准备性能
数据库版本为SQL Server2008R2,利用微软的之前的案例库(Northwind)进行分析,部份内容也会应用微软的另外一个案例库AdventureWorks学习
相信了解SQL Server的朋友,对这两个库都不会太陌生。优化
概念理解url
关于SQL Server中的统计信息,在联机丛书中是这样解释的spa
查询优化的统计信息是一些对象,这些对象包含与值在表或索引视图的一列或多列中的分布有关的统计信息。查询优化器使用这些统计信息来估计查询结果中的基数或行数。经过这些基数估计,查询优化器能够建立高质量的查询计划。例如,查询优化器可使用基数估计选择索引查找运算符而不是耗费更多资源的索引扫描运算符,从而提升查询性能。3d
其实关于统计信息的做用通俗点将就是:SQL Server经过统计信息理解库中每张表的数据内容项分布,知道里面数据“长得啥德行,作到心中有数”,这样每次查询语句的时候就能够根据表中的数据分布,基本能定位到要查找数据的内容位置。
好比,我记得我之前有篇文章写过一个相同的查询语句,可是产生了彻底不一样的查询计划,这里回顾下,基本以下:
SELECT * FROM Person.Contact WHERE FirstName LIKE 'K%' SELECT * FROM Person.Contact WHERE FirstName LIKE 'Y%'
彻底相同的查询语句,只是查询条件不一样,一个查找以K开头的顾客,一个查找以Y开头的顾客,却产生了彻底不一样的查询计划。
其实,这里的缘由就是统计信息在做祟。
咱们知道,在这张表的FirstName字段存在一个非汇集索引,目标就是为了提高如上面的查询语句的性能。
可是这张表里面FirstName字段中的数据内容以K开头的顾客存在1255行,也就是若是利用非汇集索引查找的方式,须要产生1225次IO操做,这可能不是最糟的,糟的还在后面,由于咱们获取的数据字段并不所有在FirstName字段中,而须要额外的书签查找来获取,而这个书签查找会产生的大量的随机IO操做。记住:这里是随机IO。关于这里的查找方式在咱们第一篇文章中就有介绍。
因此相比利用非汇集索引所带来的消耗相比,所有的因此索引扫描来的更划算,由于它依次扫描就能够获取想要的数据。
而以Y开头的就只有37行,37行数据彻底经过非汇集索引获取,再加一部分的书签查找很显然是一个很划算的方式。由于它数据量少,产生的随机IO量相对也会少。
因此,这里的问题来了:
SQL Server是如何知道这张表里FirstName字段中以K开头的顾客会比较多,而以Y开头反而少呢?。
这里就是统计信息在做祟了,它不但知道FirstName字段中各行数据的内容“长啥样”,而且仍是知道每行数据的分布状况。
其实,这就比如在图书库中,每一个书架就是一张表,而每本书就是一行数据,索引就好像图书馆书籍列表,好比按类区分,而统计信息就好像是每类书籍的多少以及存放书架位置。因此你借一本书的时候,须要借助索引来查看,而后利用统计信息指导位置,这样才能获取书本。
但愿这样解释,看官已经明白了统计信息的做用了。
这里多谈点,有不少童鞋没有深刻了解索引和统计信息的做用前提下,在看过不少调优的文章以后,只深谙了一句话:调优嘛,建立索引就好了。
我不否定建立索引这种方式调优方式的做用性,可是不少时候关于建索引的技巧却不了解。更巧的是大部分状况下属于误打误撞建立完索引后,性能果然提高了,而有时候建立的索引却毫无用处,只会影响表的其它操做的性能(尤为是Insert),更有甚者会产生死锁状况。
并且,关于索引项的做用,其实不少的状况下,并不想你想象的那么美好,后续文章咱们会分析那些索引失效的缘由。
因此遇到问题,其实还要经过表象理解其本质,这样才能作到真正的有的放矢,有把握的解决问题。
解析统计信息
咱们来详细分析一下统计信息中的内容项,咱们知道在上面的语句中,在表Customers中ContactName列中存在一个非汇集索引项,因此在该列存在统计信息,咱们能够经过以下脚本查看该表的统计信息列表
sp_helpstats Customers
而后经过如下命令来查看该统计信息的详细内容,代码以下
DBCC SHOW_STATISTICS(Customers,ContactName)
每个统计信息的内容都包含以上三部分的内容。
咱们依次来分析下,经过这三部份内容SQL Server如何了解该列数据的内容分布的。
a、统计信息的整体属性项
该部分包含如下几列:
通过上面部分的数据,统计信息已经分析出该列数据的最近更新时间、数据量、数据长度、数据类型等信息值。
b、统计信息的覆盖索引项
All density:反映索引列的稠密度值。这是一个很是重要的值,SQL Server会根据这个评分项来决定该索引的有效程度。
该分值的计算公式为:density=1/表中非重复的行数。因此该稠密度值取值范围为:0-1。
该值越小说明该列的索引项选择性更强,也就说该索引更有效。理想的状况是所有为非重复值,也就是说都是惟一值,这样它的数最小。
举个例子:好比上面的例子该列存在91行,假如顾客不存在重名的状况下,那么该密度值就为1/91=0.010989,该列为性别列,那么它只存在两个值:男、女,那么该列的密度值就为0.5,因此相比而言SQL Server在索引选择的时候很显然就会选择ContactName(顾客名字)列。
简单点讲:就是当前索引的选择性高,它的稠密度值就小,那么它就重复值少,这样筛选的时候更容易找到结果值。相反,重复值多选择性就差,好比性别,一次过滤只能过滤掉一半的记录。
Average Length:索引的平均长度。
Columns:索引列的名称。这里由于咱们是非汇集索引,因此会存在两行,一行为ContactName索引列,一行为ContactName索引列和汇集索引的列值CustomerID组合列。但愿能明白这里,索引基础知识。
经过以上部分信息,SQL Server会知道该部分的数据获取方式那个更快,更有效。
c、统计信息的直方图信息
咱们接着分析第三部分,该列直方图信息,经过这块SQL Server能直观“掌控”该列的数据分布内容,咱们来看
通过最后一部分的描述,SQL Server已经彻底掌控了该表中该字段的数据内容分布了。想获取那些数据根据它就能够从容获取到,而且统计信息是排序了的。
因此当咱们每次写的T-SQL语句,它都能根据统计信息评估出要获取的数据量多少,而且找到最合适的执行计划来执行。
我也相信通过上面三部分的分析,关于文章开篇咱们提到的那个关于‘K’和‘Y’的问题会找到答案了,这里不解释了。
固然,若是数据量特别大,统计信息的维护也会有小小的失误,而这时候就须要咱们来站出来及时的弥补。
建立统计信息
经过上面的介绍,其实咱们已经看到了统计信息的强大做用了,因此对于数据库来讲它的重要性就不言而喻了,所以,SQL Server会自动的建立统计信息,适时的更新统计信息,固然咱们能够关闭掉,可是我很是不建议这么作,缘由很简单:No Do No Die...
这两项功能默认是开启的,也就是说SQL Server会本身维护统计信息的准确性。
在平常维护中,咱们大可没必要要去更改这两项,固然也有比较极端的状况,由于咱们知道更新统计信息也是一个消耗,在很是的大的并发的系统中须要关掉自动更新功能,这种状况很是的少之又少,因此基本采用默认值就能够。
在如下状况下,SQL Server会自动的建立统计信息:
一、在索引建立时,SQL Server会自动的在索引列上建立统计信息。
二、当SQL Server想要使用某些列上的统计信息,发现没有的时候,这时候会自动建立统计信息。
三、固然,咱们也能够手动建立。
好比,自动建立的例子
select * into CustomersStats from Customers sp_helpstats CustomersStats
来添加一个查询语句,而后再查看统计信息
select * from CustomersStats where ContactName='Hanna Moos' go sp_helpstats CustomersStats go
固然,咱们也能够根据本身的状况来手动建立,建立脚本以下
USE [Northwind]
GO
CREATE STATISTICS [CoustomersOne] ON [dbo].[CustomersStats]([CompanyName])
GO
SQL Server也提供了GUI的图像化操做窗口,方便操做
在如下状况下,SQL Server会自动的更新统计信息:
一、若是统计信息是定义在普通的表格上,那么当发生如下任一种的变化后,统计信息就会被触发更新动做。
二、临时表上也能够有统计信息。这也是不少状况下采用临时表优化的缘由之一。其维护策略基本和普通表格同样,可是表变量不能建立统计信息。
固然,咱们也能够手动的更新统计信息,更新脚本以下:
UPDATE STATISTICS Customers WITH FULLSCAN
文章写的有点糙....但篇幅已经稍长了....先到此吧...后续我再补充一部分关于统计信息的内容。
关于调优内容太普遍,咱们放在之后的篇幅中介绍,有兴趣的能够提早关注。
参考文献
有问题能够留言或者私信,随时恭候有兴趣的童鞋加入SQL SERVER的深刻研究。共同窗习,一块儿进步。
文章最后给出前面几篇的链接,如下内容基本涵盖咱们平常中所写的查询运算的分解,看来有必要整理一篇目录了.....
-----------------如下进阶篇-------------------
SQL Server调优系列进阶篇(查询语句运行几个指标值监测)
若是您看了本篇博客,以为对您有所收获,请不要吝啬您的“推荐”。