一、统计信息数据库
SQL SERVER是根据表中的统计信息进行行数估计,按照脚本语义来肯定物理操做步骤生成执行计划,再按照该执行计划访问数据。表和视图都有统计信息,统计信息对象是根据索引或表列的列表建立的。当某列第一次最为条件查询时,将建立单列的统计信息。当建立索引时,将建立同名的统计信息。索引中,统计信息只统计首列,所以索引除了按首列排序存储数据外,其统计信息也是按首列计算统计的,因此索引设置时定义的第一列很是重要。每一个统计信息对象都在包含一个或多个表列的列表上建立,而且包括显示值在第一列中的分布的直方图。如下状况适用时,考虑使用 CREATE STATISTICS 语句建立统计信息:
① 数据库引擎优化顾问建议建立统计信息。
② 查询谓词包含尚不位于相同索引中的多个相关列。
③ 查询从数据的子集中选择数据。
④ 查询缺乏统计信息。优化
二、查看统计信息spa
select * from sys.stats where object_id=OBJECT_ID(N'[Sales].[SalesOrderDetail]')
三、查看一张表的某个索引的统计信息3d
先查看整个数据库的索引code
SELECT * FROM sys.sysindexes
查看表的索引的统计信息对象
DBCC SHOW_STATISTICS ('tb_medicine' ,'pk_medic_3124D5480BC6C34E');
四、先建立一个汇集索引blog
DROP INDEX pk_medic_3124D5480BC6C34E ON tb_medicine
CREATE CLUSTERED INDEX ci_name
ON tb_medicine
(药品名称 ASC);
查看统计信息排序
DBCC SHOW_STATISTICS ('tb_DrugsRegistration' ,'ci_name');
在执行一次查询语句索引
select d.*from tb_DrugsRegistration as d where d.name ='硝苯地平'
注意:查看估计行数,系统会在创建索引以后自动创建一个统计的信息,进行一个摸底的排查,对比真正查询出来的一个统计行数,能够看出估计出的行数较为准确,可是也存在误差不少的由于查询是系统会隐藏某些药品的名字,在查询这些被隐藏的名字的时候,系统就会用隐藏的总行数除以隐藏的种类,获得一个估计的结果,只是取一个均值。ci
5、删除多余的tb_medicine表的某个相同行数的药品行数,查看药品名称为依替米星的估计行数,再执行查询语句
DELETE TOP(3) tb_medicine SELECT O.* FROM tb_medicine AS O WHERE o.name like '依替米星%';
注意:由上面的查询结果能够看得出来,删除记录以后系统就能够进行一个样本的采集,但这个采集只是随意的,短暂的,所以存在偏差。
下面就要对索引进行一个手动的更新(使用完整扫描)
UPDATE STATISTICS tb_medicne ci_name
WITH FULLSCAN;
再次查询统计信息
DBCC SHOW_STATISTICS ('tb_DrugsRegistration' ,'ci_name');
六、总结:对于改天查询中的一个参数或多个参数值致使查询执行时间差别很大的语句,多半是Statistics没有及时跟上,咱们须要手动更新一下。在以后咱们观察这个索引的自动更新统计是否为ON,若是配置正常可是Statistics还不能及时跟上的建议创建一个job按期检查统计信息更新状况并处理。
SQL Server基于开销(Cost)评估执行计划,选择开销最小的做为“最优化”的执行计划,因为SQL Server根据索引及其统计信息来计算开销,因此,对查询优化来讲,索引和统计数据是很是重要的,查询优化器(Query Optimizer)使用统计信息对查询的开销进行评估(Estimate),选择开销小的查询计划,做为最终的、“最优的”的执行计划。