SQL Server查询分析器是基于开销的。一般来说,查询分析器会根据谓词来肯定该如何选择高效的查询路线,好比该选择哪一个索引。而每次查询分析器寻找路径时,并不会每一次都去统计索引中包含的行数,值的范围等,而是根据必定条件建立和更新这些信息后保存到数据库中,这也就是所谓的统计信息。数据库
查看SQL Server的统计信息很是简单,使用以下指令:性能
DBCC SHOW_STATISTICS('表名','索引名')测试
所获得的结果如图1所示。优化
图1.统计信息spa
下面咱们经过一个简单的例子来看统计信息是如何影响查询分析器。我创建一个测试表,有两个INT值的列,其中id为自增,ref上创建非汇集索引,插入100条数据,从1到100,再插入9900条等于100的数据。图1中的统计信息就是示例数据的统计信息。blog
此时,我where后使用ref值做为查询条件,可是给定不一样的值,咱们能够看出根据统计信息,查询分析器作出了不一样的选择,如图2所示。索引
图2.根据不一样的谓词,查询优化器作了不一样的选择get
其实,对于查询分析器来讲,柱状图对于直接能够肯定的谓词很是管用,这些谓词好比:qt
where date = getdate() 效率
where id= 12345
where monthly_sales < 10000 / 12
where name like “Careyson” + “%”
可是对于好比
where price = @vari
where total_sales > (select sum(qty) from sales)
where a.id =b.ref_id
where col1 =1 and col2=2
这类在运行时才能知道值的查询,采样步长就明显不是那么好用了。另外,上面第四行若是谓词是两个查询条件,使用采样步长也并很差用。由于不管索引有多少列,采样步长仅仅存储索引的第一列。当柱状图再也不好用时,SQL Server使用密度来肯定最佳的查询路线。
密度的公式是:1/表中惟一值的 个数。当密度越小时,索引越容易被选中。好比图1中的第二个表,咱们能够经过以下公式来计算一下密度:
图3.某一列的密度
根据公式能够推断,当表中的数据量逐渐增大时,密度会愈来愈小。
对于那些不能根据采样步长作出选择的查询,查询分析器使用密度来估计行数,这个公式为:估计的行数=表中的行数*密度
那么,根据这个公式,若是我作查询时,估计的行数就会为如图4所示的数字。
图4.估计的行数
咱们来验证一下这个结论,如图5所示。
图5.估计的行数
所以,能够看出,估计的行数是和实际的行数有出入的,当数据分布均匀时,或者数据量大时,这个偏差将会变的很是小。
由上面的例子能够看到,查询分析器因为依赖于统计信息进行查询,那么过期的统计信息则可能致使低效率的查询。统计信息既能够由SQL Server来进行管理,也能够手动进行更新,也能够由SQL Server管理更新时手动更新。
当开启了自动更新后,SQL Server监控表中的数据更改,当达到临界值时则会自动更新数据。这个标准是:
上述条件的知足均会致使统计被更新。
固然,咱们也可使用以下语句手动更新统计信息。
UPDATE STATISTICS 表名[索引名]
SQL Server还能够针对不属于任何索引的列建立统计信息来帮助查询分析器获取”估计的行数“.当咱们开启数据库级别的选项“自动建立统计信息”如图6所示。
图6.自动建立统计信息
当这个选项设置为True时,当咱们where谓词指定了不在任何索引上的列时,列的统计信息会被建立,可是会有如下两种状况例外:
咱们能够经过系统视图sys.stats来查看这些统计信息,如图7所示。
图7.经过系统视图查看统计信息
固然,也能够经过以下语句手动建立统计信息:
CREATE STATISTICS 统计名称 ON 表名 (列名 [,...n])
本文简单谈了统计信息对于查询路径选择的影响。过期的统计信息很容易形成查询性能的下降。所以,按期更新统计信息是DBA重要的工做之一。