写在前面:这是第一篇T-SQL查询高级系列文章.但是T-SQL查询进阶系列还远远没有写完。这个主题放到高级我想是因为这个主题需要一些进阶的知识作为基础..如果文章中有错误的地方请不吝指正.本篇文章的内容需要索引的知识作为基础。

简介


在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 SERVER中非聚集索引的覆盖,连接,交叉和过滤相关推荐

  1. 重新理解SQL Server的聚集索引表与堆表

    目录 目录 简述SQL Server表的类型 如何区分聚集索引表与堆表 聚集索引表与堆表的正确使用 参考资料 简述SQL Server表的类型 由于当前关系型数据库(RDBMS)种类繁多,存在对标准S ...

  2. sql聚集索引和非聚集索引_SQL Server中非聚集索引概述

    sql聚集索引和非聚集索引 This article gives an introduction of the non-clustered index in SQL Server using exam ...

  3. SQL Server的聚集索引和非聚集索引

    微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引.簇集索引)和非聚集索引(nonclustered index,也称非聚类索引.非簇集索引)-- (一) ...

  4. CREATE VIEW SQL:在SQL Server中使用索引视图

    This is the fourth article in a series of learning the CREATE VIEW SQL statement. So far, we have do ...

  5. 理解SQL Server中索引的概念,原理以及其他

    简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,SQL Server仍然可以实现应有的功能.但索引可以在大多数情况下大大提升查询性能,在OLAP中尤其明显.要完全理解索 ...

  6. T-SQL查询进阶--理解SQL Server中索引的概念,原理以及其他(看了两次了,转了)

    简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,SQL Server仍然可以实现应有的功能.但索引可以在大多数情况下大大提升查询性能,在OLAP中尤其明显.要完全理解索 ...

  7. 理解SQL Server中索引的概念,原理

    理解SQL Server中索引的概念,原理 摘自:http://51even.iteye.com/blog/1490412 简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索 ...

  8. SQL Server 深入解析索引存储(非聚集索引)

    标签:SQL SERVER/MSSQL SERVER/数据库/DBA/索引体系结构/非聚集索引 概述 非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点: 基础表的数据行不按非 ...

  9. SQL SERVER全面优化-------索引有多重要?

    想了好久索引的重要性应该怎么写?讲原理结构?我估计大部分人不愿意看,也不愿意花那么多时间仔细研究.光写应用?感觉不明白原理一样不会用.举例说明?情况太多也写不全....到底该怎么写呢? 随便写吧,想到 ...

最新文章

  1. 一款比较实用齐全的jQuery 表单验证插件
  2. android webview 填充,从Android使用WebView自动填充表格
  3. dnn5.5.1的配置
  4. Jdk8一行代码读取文件
  5. 使用绝对布局的方法创建一个登录密码验证的简易窗口
  6. python--pdb
  7. 又一例两块硬盘离线的数据恢复成功案例
  8. 探索 OpenStack 之(7):Neutron 深入探索之 Open vSwitch (OVS) + GRE 之 Neutron节点篇
  9. ubuntu-多网卡聚合-bond技术教程
  10. 常用实例:js格式化手机号为3 4 4形式
  11. 清除windows 系统中 任意已安装任意版本的 .NET Framework
  12. 支付宝第三方登录集成文档
  13. Codeforces 1389 C. Good String(枚举)
  14. 【数据结构与算法】学习笔记-《算法笔记》-7
  15. C++制作打字小游戏
  16. C语言中变量和函数的声明与定义
  17. QQ浏览器如何安装油猴插件
  18. 自己写一个composers包【一】
  19. 魔兽世界怀旧服务器无限刷怪点,魔兽世界怀旧服:50级物理刷怪升级攻略!无干扰每小时4万经验!...
  20. oracle数据库variable,oracle中的define,declare,variable的差别

热门文章

  1. C++happy number开心数的实现算法(附完整源码)
  2. 1.15.Flink state(状态)管理与恢复、什么是state、Keyed State、Operator State、状态容错(生成快照,恢复快照),checkPoint简介,重启策略等
  3. 14_pytorch.where,pytorch.gather
  4. idea maven打包_20201116(Maven学习)
  5. html登录界面设计代码_Python登录豆瓣并爬取影评
  6. cad块炸开软件_CAD软件中将CAD图形定义为旋转动态块的操作技巧
  7. QApplication和QCoreApplication区别
  8. 深度学习: 从 RoIPooling 到 RoIAlign
  9. SSD(Single Shot MultiBox Detector):因为数据集中图像通道数不对导致的训练异常
  10. 高人对libsvm的经典总结(全面至极)