本文是转载,原文地址 http://tech.it168.com/a2011/1228/1295/000001295176.shtml

在SQL SERVER中,非聚集索引其实可以看作是一个含有聚集索引的表.但相比实际的表而言.非聚集索引中所存储的表的列数要窄很多,因为非聚集索引仅仅包含原表中非聚集索引的列和指向实际物理表的指针。

   并且,对于非聚集索引表来说,其中所存放的列是按照聚集索引来进行存放的.所以查找速度要快了很多。但是对于性能的榨取来说,SQL SERVER总是竭尽所能,假如仅仅是通过索引就可以在B树的叶子节点获取所需数据,而不再用通过叶子节点上的指针去查找实际的物理表,那性能的提升将会 更胜一筹.

  下面我们来看下实现这一点的几种方式.

  非聚集索引的覆盖

  正如前面简介所说。非聚集索引其实可以看作一个聚集索引表.当这个非聚集索引中包含了查询所需要的所有信息时,则查询不再需要去查询基本表,而仅仅是从非聚集索引就能得到数据:

  下面来看非聚集索引如何覆盖的:

  在adventureWorks的SalesOrderHeader表中,现在只有CustomerID列有非聚集索引,而BillToAddressID没有索引,我们的查询计划会是这样:

  查询会根据CustomerID列上的非聚集索引找到相应的指针后,去基本表上查找数据.从执行计划可以想象,这个效率并不快。

  下面我们来看覆盖索引,通过在CustomerID和BillToAddressID上建立非聚集索引,我们覆盖到了上面查询语句的所有数据:

  通过覆盖索引,可以看到执行计划简单到不能再简单,直接从非聚集索引的叶子节点提取到数据,无需再扫描基本表!

  这个性能的提升可以从IO统计看出来,下面我们来看有覆盖索引和没有覆盖索引的IO对比:

  索引的覆盖不仅仅带来的是效率的提升,还有并发的提升,因为减少了对基本表的依赖,所以提升了并发,从而减少了死锁!

  理解INCLUDE的魔力

  上面的索引覆盖所带来的效率提升就像魔术一样,但别着急,正如我通篇强调的一样,everything has price.如果一个索引包含了太多的键的话,也会带来很多副作用。INCLUDE的作用使得非聚集索引中可以包含更多的列,但不作为“键”使用。

  比如:假设我们上面的那个查询需要增加一列,则原来建立的索引无法进行覆盖,从而还需要查找基本表:

  但是如果要包含SubTotal这个总金额,则索引显得太宽,因为我们的业务很少根据订单价格作为查询条件,则使用INCLUDE建立索引:

  理解INCLUDE包含的列和索引建立的列可以这样理解,把上述建立的含有INCLUDE的非聚集索引想像成:

  使用INCLUDE可以减少叶子“键”的大小!

  非聚集索引的交叉

  非聚集索引的交叉看以看作是覆盖索引的扩展!

  由于很多原因,比如:

  在生产环境中,我们往往不能像上面建立覆盖索引那样随意改动现有索引,这可能导致的结果是你会更频繁的被客户打电话“关照”

  现有的非聚集索引已经很“宽”,你如果继续拓宽则增改查带来的性能下降的成本会高过提高查询带来的好处

  这时候,你可以通过额外建立索引。正如我前面提到的,非聚集索引的本质是表,通过额外建立表使得几个非聚集索引之间进行像表一样的Join,从而使非聚集索引之间可以进行Join来在不访问基本表的情况下给查询优化器提供所需要的数据:

  比如还是上面的那个例子.我们需要查取SalesOrderHeader表,通过BillToAddressID,CustomerID作为选择条件,可以通过建立两个索引进行覆盖,下面我们来看执行计划:

  非聚集索引的连接

  非聚集索引的连接实际上是非聚集索引的交叉的一种特例。使得多个非聚集索引交叉后可以覆盖所要查询的数据,从而使得从减少查询基本表变成了完全不用查询基本表:

  比如还是上面那两个索引,这时我只查询非聚集索引中包含的数据,则完全不再需要查询基本表:

  看起来这样的查询意义不大?但当你把查询条件变为<号时呢?或者给定范围时。还是有一定实际意义的。

  非聚集索引的过滤

  很多时候,我们并不需要将基本表中索引列的所有数据全部索引,比如说含有NULL的值不希望被索引,或者根据具体的业务场景,有一些数据我们不想索引。这样可以:

  减少索引的大小

  索引减少了,从而使得对索引的查询得到了加速

  小索引对于增删改的维护性能会更高

  比如说,如下语句:

  我们为其建立聚集索引后:

  这时我们为其加上过滤条件,形成过滤索引:

  由上面我们可以看出,使用过滤索引的场景要和具体的业务场景相关,对于为大量相同的查询条件建立过滤索引使得性能进一步提升!

  总结

   本文从介绍了SQL SERVER中非聚集索引的覆盖,连接,交叉和过滤。对于我们每一点从SQL SERVER榨取的性能的提升往往会伴随着另一方面的牺牲。作为数据库的开发人员或者管理人员来说,以全面的知识来做好权衡将会是非常重要.系统的学习数 据库的知识不但能大量减少逻辑读的数据,也能减少客户打电话"关照”的次数:-)

SQL查询优化:详解SQL Server非聚集索引(转载)的更多相关文章

  1. SQL Server 非聚集索引的覆盖,连接,交叉和过滤 <第二篇>

    在SQL Server中,非聚集索引其实可以看做是一个含有聚集索引的表,但相对实际的表来说,非聚集索引中所存储的表的列数要少得多,一般就是索引列,聚集键(或RID).非聚集索引仅仅包含源表中的非聚集索 ...

  2. ORACLE PL/SQL编程详解(转)

    原帖地址:http://blog.csdn.net/chenjinping123/article/details/8737604 ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语 ...

  3. SQL Server中的联合主键、聚集索引、非聚集索引、mysql 联合索引

    我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...

  4. SQL Server 索引和表体系结构(非聚集索引)

    非聚集索引 概述 对于非聚集索引,涉及的信息要比聚集索引更多一些,由于整个篇幅比较大涉及接下来的要写的“包含列的索引”,“索引碎片”等一些知识点,可能要结合起来阅读理解起来要更容易一些.非聚集索引和聚 ...

  5. SQL Server临界点游戏——为什么非聚集索引被忽略!

    当我们进行SQL Server问题处理的时候,有时候会发现一个很有意思的现象:SQL Server完全忽略现有定义好的非聚集索引,直接使用表扫描来获取数据.我们来看看下面的表和索引定义: CREATE ...

  6. SQL Server索引 (原理、存储)聚集索引、非聚集索引、堆 <第一篇>

    一.存储结构 在SQL Server中,有许多不同的可用排列规则选项. 二进制:按字符的数字表示形式排序(ASCII码中,用数字32表示空格,用68表示字母"D").因为所有内容都 ...

  7. SQL Server索引 - 聚集索引、非聚集索引、非聚集唯一索引 <第八篇>

    聚集索引.非聚集索引.非聚集唯一索引 我们都知道建立适当的索引能够提高查询速度,优化查询.先说明一下,无论是聚集索引还是非聚集索引都是B树结构. 聚集索引默认与主键相匹配,在设置主键时,SQL Ser ...

  8. SQL Server索引 - 非聚集索引 <第七篇>

    一.非聚集索引维护 非聚集索引的行定位器值保持相同的聚集索引值,即使该聚集索引列物理上重新定位后,也是如此. 为了优化这个维护开销,SQL Server添加一个指向旧数据页的指针,以在页面分割之后指向 ...

  9. SQL Server - 索引详细教程 (聚集索引,非聚集索引)

    转载自:https://www.cnblogs.com/hyd1213126/p/5828937.html 作者:爱不绝迹 (一)必读:深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录. ...

随机推荐

  1. android 监听动画对象后不能播放动画

    采用监听  AnimationListener 发现不能播放动画了. 解决办法: 将动画的启动方式:animation.startnow去掉,改为如下即可 view.startAnimation(an ...

  2. 关于Unity中NGUI的Pivot和锚点

    Pivot 1.创建一个Sprite类型的Sprite1节点,关联一个图集和一张贴图,用图中的六个按钮调整这个贴图的Pivot点,一共有八个点可以选择 2.再创建一个Sprite类型的Sprite2节 ...

  3. 深度学习的batch_size

    知乎讨论: https://www.zhihu.com/question/61607442/answer/204675996 案例一 http://www.myzaker.com/article/5a ...

  4. oracle 11g 使用物化视图远程增量刷新数据

    ① 源数据库建立物化视图日志 drop MATERIALIZED VIEW LOG ON ORG_BASEINFO/ CREATE MATERIALIZED VIEW LOG ON ORG_BASEI ...

  5. 纯CSS3冒泡动画按钮实现教程

    这款CSS3动画按钮非常的有创意,鼠标在滑过按钮时并不像其他按钮那样仅仅改变按钮的背景颜色,而是出现很酷的冒泡动画.这么惊艳的CSS3动画按钮,这篇文章主要将按钮实现的过程和代码分享给大家,希望能给在 ...

  6. centos7 centos中apache运行php需要连接mysql一直连不上,telnet访问mysql出错Connection closed by foreign host

    执行命令: getsebool -a|grep httpd 发现 httpd_can_network_connect off 解决:  setsebool httpd_can_network_conn ...

  7. 《objective-c基础教程》学习笔记(五)—— 继承方法

    在上一篇博文中,我们将原先的纯C语言代码,编写成了用Objective-C(后面直接缩写成OC)的写法.使得代码在易读性上有明显提升,结构也更清晰.同时,也对面向对象的概念有了进一步的介绍和加深. 但 ...

  8. 【代码审计】五指CMS_v4.1.0 后台存在SQL注入漏洞分析

      0x00 环境准备 五指CMS官网:https://www.wuzhicms.com/ 网站源码版本:五指CMS v4.1.0 UTF-8 开源版 程序源码下载:https://www.wuzhi ...

  9. redis最大缓存和回收策略

  10. 【typecho】解决使用分隔符 <!--more-->标签后首页文字下面出现一段空白

    使用typecho 搭建了一个站点,输出摘要时候.使用了   <!--more-->  分隔符,然后首页文章出现了一大片空白,审查元素发现.多了好多 <br> 标签 解决办法: ...