一、索引在查询优化中的角色

  SQL Server的查询优化器是基于开销的优化器、它通过确认选择性、数据的唯一性以及过滤数据(通过WHERE或JOIN子句)所使用的列来决定最佳的数据访问机制。统计与索引一同存在,但是它们也作为断言的一部分存在于没有索引的列上。

  作为谓词引用的列中数据分布的最新信息帮助优化器确定所使用的查询策略。在SQL Server中,这个信息以统计的形式维护,这对于基于开销的优化器创建一个有效的查询执行计划是很重要的。通过统计,优化器能做出返回结果集或中间结果集所花费时间的精确估计,从而确定最高效的操作。只要确定数据库已经进行了默认的统计设置,优化器就能尽其所能地动态确定有效的处理策略。而且,作为性能问题诊断时的安全性度量,应该确定自动统计维护历程正在按照预想工作。如果有必要,甚至手工控制统计的创建或维护。

二、索引列上的统计

  索引的有效性完全取决于索引列上的统计。如果没有统计,SQL Server的基于开销的查询优化器将不能选择到使用索引最有效的方式。

  SQL Server默认会自动创建索引键的统计,不管它是何时创建的。

  我们知道,随着数据的变化,保持查询低开销的数据检索机制也会变化。例如,如果一个表对于某个列的值的选择性相当高为0.99,那么通过该列上的非聚集索引来检索匹配行是有意义的。但是如果表中数据变化,添加了大量该列有相同值的行选择性下降,那么使用这个非聚集索引就不再有意义。

  SQL Server可以使一个索引上的统计随着索引列内容变化而更新。默认情况下,这个特性被开启,而且可以通过属性=》选项=》数据库的自动更新统计设置来开启或关闭。

  

  更新统计消耗额外的CPU周期。为了优化和更新进行,SQL Server使用如下高效的算法来确定合适的更新统计时机:

  1. 当没有任何行的表得到一个行时;
  2. 当少于500行的表增加500行或更多行时;
  3. 当多于500行的表增加500+20%的行数时;

  这种内建的智能使每个进程的CPU利用率保持很低。也可以异步地更新统计。这意味着当查询正常地导致统计更新时,查询使用旧的统计继续,统计被离线更新。这可以加速一些查询的响应时间,比如在数据库很大或超时间隔很短时。

  可以使用ALTER DATABASE命令手工禁用(或启用)自动更新统计和异步更新统计特性,默认情况下,自动更新统计特性被启用(强烈建议保持启用)。自动异步更新统计特性默认下被禁用,只有确定它能在数据库上对超时有帮助时才开启这一特性。

  1、更新统计的好处以及过时统计的缺点示例

  执行自动更新的好处通常要超过其在系统资源上的开销,自动更新统计能够有效帮助SQL Server查询优化器获得最佳的数据访问途径。

  为了更直接地控制数据的行为,下面来搞个示例实战下,我们有一张Person表,里面有1万条数据左右。

  

  Id列原本是主键,但现在被撤掉了,因此选择性非常高,我们来看看如下SQL语句的执行计划与数据页读取情况:

  

  由执行计划来看,这是一个典型的书签查找,查询返回1条记录,有效地使用了索引。

  

  下面,我们来插入3000条Id为2的记录:

  DECLARE @i int;
  SET @i = 0;
  WHILE (@i < 3000)
  BEGIN
  INSERT INTO PersonTenThousand (Id,PId,Name) VALUES(2,3,'相同Id号')
  SET @i = @i + 1;
  END

  注意:由于SQL Server的索引更新机制,大于500条数据的情况下,插入数量要大于20%的情况下,才会自动更新索引。

  现在再来执行相同的语句以及查询计划:

  

  

  我们看到,由于索引的自动更新机制,执行计划改变了,SQL Server认为对于返回3000条记录,使用表扫描要优于执行3000次书签查找。

  下面,我们来重复一次,先删除原有的3000条Id为2的记录,这次我们先关闭索引统计再插入3000条记录。

  --关闭自动统计索引
  ALTER DATABASE DataExample SET AUTO_UPDATE_STATISTICS OFF

  

  

  我们看到,索引统计的不更新,导致SQL Server仍然使用原来的执行计划,进行了3000多次查找,逻辑读上升。

  这是为什么呢?因为统计不更新了,SQL Server并不知道Id=2多了3000条记录,还是以为Id=2的记录只有一条,因此就使用了索引进行书签查找。

  小结:过时的索引统计会导致SQL Server根据旧的统计执行计划,而实际上这些执行计划在数据更新后可能并不是最优的。因此,最好保持索引的自动更新。

 
 

索引列上的统计 <第一篇>的更多相关文章

  1. 非索引列上的统计 <第二篇>

    非索引列上的统计 有时候,可能在连接或过滤条件中的列上没有索引.即使对这种非索引列,如果查询优化器知道这些列的数据分布(统计),它也很可能做出最佳的选择. 除了索引上的统计,SQL Server可以在 ...

  2. UNIQUEIDENTIFIER列上的统计信息

    UNIQUEIDENTIFIER列上的统计信息非常有意思,在它上面有一些很令人讨厌的行为.我们来看下. 问题重现(The repro) 为了向你展示我们刚抱怨的行为,我用下列简单的表定义创建了一个数据 ...

  3. Windows系统CPU内存网络性能统计第一篇 内存

    最近翻出以前做过的Windows系统性能统计程序,这个程序可以统计系统中的CPU使用情况,内存使用情况以及网络流量.现在将其整理一下(共有三篇),希望对大家有所帮助. 目录如下: 1.<Wind ...

  4. oracle避免在索引列上使用NOT

    通常, 我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的 影响. 当ORACLE”遇到”NOT,他就会停止使用索引转而执行全表扫描. 举例: 低效: (这里,不使用索引) S ...

  5. 避免在WHERE条件中,在索引列上进行计算或使用函数,因为这将导致索引不被使用

    点击(此处)折叠或打开 --在sal列上创建非唯一索引 scott@TESTDB11>create index idx_emp1_sal on emp1(sal); Index created. ...

  6. oracle避免在索引列上使用IS NULL和IS NOT NULL

    避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引 .对于单列索引,如果列包含空值,索引中将不存在此记录. 对于复合索引,如果每个列都为空,索引中同样不存在此记录. 如果至少有一个列不为空 ...

  7. oracle避免在索引列上使用计算

    WHERE子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描. 举例: 低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000; 高效: SE ...

  8. 这是我在word 2010上发布的第一篇文章

    1.设置word 2010,添加cnblogs帐户 配置参考链接 其中URL地址为: http://rpc.cnblogs.com/metaweblog/fariver,在cnblogs配置的最下方可 ...

  9. SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)

    本文出处:http://www.cnblogs.com/wy123/p/6008477.html 关于统计信息对数据行数做预估,之前写过对非相关列(单独或者单独的索引列)进行预估时候的算法,参考这里. ...

随机推荐

  1. Cmake,source_group

    Cmake的source_group命令相当于VS里面给编译需要的文件归类,把一些相同性质的文件放一个类里面,这些“类”,可以在VS 图形界面下左边(一般情况下),看到header文件夹下面的H文件, ...

  2. [置顶] 【原创分享】嵌入式linux应用之内核移植定制篇-前篇(linux-3.8.12 mini2440)--20130824

    移植的话其实很早就做过了,不过那时用的友善定制的老版本2.6.32 驱动什么的全部弄好了,仅仅用默认配置而已.基本不用改动什么,很简单. 内核更新其实非常的快,今天我就用个3.8.12来移植. 当然, ...

  3. bzoj3174 [Tjoi2013]拯救小矮人

    Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人, ...

  4. Codeforce 220 div2

    D 插入: 在当前指针位置sz处插入一个1,col[sz]记录插入的内容,sz++; 删除i: 找到第i个1的位置,赋为0; 于是转化为一个维护区间和的问题; trick: 如果是依次删除a[0],a ...

  5. Mybatis 开发中遇见的异常及处理

    1 异常信息: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.Bin ...

  6. hdu 5313 Bipartite Graph(dfs染色 或者 并查集)

    Problem Description Soda has a bipartite graph with n vertices and m undirected edges. Now he wants ...

  7. AVR32开发环境搭建

    下面是搭建AVR32开发环境的过程记录: 1.AVR32的编译环境下载  (到这里下载  as5installer-stable-5.1.208-full.exe) 如果你在安装的过程中碰到如下问题: ...

  8. RAC 的一些概念性和原理性的知识(转)

    一 集群环境下的一些特殊问题 1.1 并发控制 在集群环境中, 关键数据通常是共享存放的,比如放在共享磁盘上. 而各个节点的对数据有相同的访问权限, 这时就必须有某种机制能够控制节点对数据的访问. O ...

  9. SQL Server常用脚本

    一.迁移登录用户脚本: select 'create login [' + p.name + '] ' + case when p.type in('U','G') then 'from window ...

  10. Fedora安装VirtualBox时出现错误Kernel driver not installed (rc=-1908)的解决办法

    新建虚拟机后启动时出现如下错误: Kernel driver not installed (rc=-1908) The VirtualBox Linux kernel driver (vboxdrv) ...