`

T-SQL查询高级--理解SQL SERVER中非聚集索引的覆盖,连接,交叉和过滤

 
阅读更多

简介


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

    1

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

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

 

非聚集索引的覆盖


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

   2

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

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

   3

 

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

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

    4

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

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

    5

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

   

 

理解INCLUDE的魔力

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

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

    6

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

    8

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

     7

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

 

 

 

非聚集索引的交叉


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

     由于很多原因,比如:

  •     在生产环境中,我们往往不能像上面建立覆盖索引那样随意改动现有索引,这可能导致的结果是你会更频繁的被客户打电话“关照”
  •     现有的非聚集索引已经很“宽”,你如果继续拓宽则增改查带来的性能下降的成本会高过提高查询带来的好处

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

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

   9

   

   

非聚集索引的连接


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

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

     10

 

非聚集索引的过滤


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

  •     减少索引的大小
  •     索引减少了,从而使得对索引的查询得到了加速
  •     小索引对于增删改的维护性能会更高

    比如说,如下语句:

    11

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

    12

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

    13

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

 

总结


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

分享到:
评论

相关推荐

    sqlserver 2008 查找缺失索引

    ### SQL Server 2008 查找缺失索引 #### 一、理解缺失索引及其查询方法 在SQL Server 2008中,优化数据库性能的一个重要方面就是确保索引设计合理。当数据库管理系统(DBMS)检测到某个查询在没有合适索引支持的...

    SQL_Server2005索引碎片分析和解决方法

    ### SQL Server 2005 索引碎片分析与解决方法 #### 一、索引碎片的概念 在SQL Server 2005中,索引是提高查询效率的重要手段之一。然而,随着数据的增删改查操作,索引可能会出现碎片化现象。碎片化的索引会导致...

    SQL-Server-2000--整套课件完整版电子教案课件汇总2.pptx

    此外,SQL Server 2000还支持事务处理、备份恢复、性能优化、索引管理、存储过程和触发器等功能,为企业级应用提供了强大的数据库支持。对于初学者,了解这些基础知识是掌握SQL Server 2000的关键。在实际应用中,...

    nc57(sql server 建库)

    通过对SQL Server中创建和管理nc57数据库的深入解析,我们不仅学习了数据库创建的基本语法,还理解了文件组、数据文件和索引文件的组织和管理方式,以及如何通过合理的规划和配置提升数据库的性能和可扩展性。...

    sql中英文单词及名词解释

    本文将对SQL中常见的英文单词及其对应的中文含义进行详细的解释,帮助初学者更好地理解并掌握SQL的基础知识。 #### 关键词汇解析 1. **Add 增加** - 在SQL中,`ADD`通常用于添加新的列或约束到现有的表结构中。 ...

    DM7_SQL语言使用手册.pdf

    支持创建、修改、删除数据库对象(如表、视图、索引等),以及进行数据操作和查询。 4. 所支持的数据类型 - 常规数据类型包括数值类型、字符类型、日期时间类型等。 - 位串数据类型支持二进制数据存储。 - 日期...

    基本SQL数据库查询语句大全

    SQL(Structured Query Language)是用于管理和处理关系数据库的标准语言,它是数据存储、检索、更新和删除的核心工具。本文将深入探讨基本的SQL查询语句,帮助你从基础开始全面掌握SQL。 1. **SELECT语句**:SQL的...

    SQL Server如何保证可空字段中非空值唯一

    在SQL Server中,确保可空字段中非空值的唯一性是一个常见的需求,尤其是在设计数据库表结构时。这里我们探讨三种方法来实现这一目标。 首先,我们看问题的背景:存在一个表`test_tb`,其中包含一个允许为空的字段`...

    SQL Server2000中的全文检索.pdf

    全文索引器是用于创建和填充全文目录的组件,这些目录存储在SQL Server的内部结构中,并由Microsoft搜索服务进行维护和管理。全文索引器的工作方式类似于传统的SQL Server索引器,它提取每行数据并将其传递给...

    21天自学SQL电子书

    - **Microsoft SQL Server Management Studio (SSMS):** 微软为SQL Server设计的工具,支持复杂的数据库管理和开发任务。 - **pgAdmin:** PostgreSQL的图形化管理工具,提供强大的数据库管理功能。 #### SQL在...

    SQL21日自学通,完整版

    - **SQL的功能**:SQL主要用于数据查询、更新、定义和控制等方面。它可以进行数据检索、插入、删除、修改等操作,并且支持复杂的查询功能。 - **SQL标准**:虽然存在多种SQL标准,但最常见的有SQL-92、SQL-99、SQL-...

    MySQL常见面试题(表连接类型,count(*),count(列),count(1)的区别,索引,存储引擎,锁,优化)

    MySQL是世界上最流行的开源关系型数据库管理系统之一,其面试题涵盖了多个方面,包括表连接类型、COUNT函数的不同用法、索引类型以及优化策略等。以下是对这些知识点的详细阐述: 1. **表连接类型** - **内连接...

    SQLServerHaving用法

    以下是从提供的部分代码中提取并重构的示例,以帮助理解如何在SQL Server中使用`HAVING`子句: ##### 示例1 ```sql SELECT OaBp_ͬId, COUNT(OaBp_ͬId) AS Counte FROM OAб깩Ӧ GROUP BY OaBp_ͬId HAVING COUNT...

    SQL教程

    ### SQL教程:21天快速上手 #### SQL简史与数据库简史 SQL(Structured Query ...接下来的一周将继续深入探索更高级的SQL特性,包括数据操作、表的创建和管理、索引和视图的使用等,进一步提升数据管理的能力。

    MySQL 精选 60 道面试题(含答案)

    - `OR`语句中非索引列 10. **字符串索引策略**: - 完整索引占用空间大,但查询效率高 - 前缀索引节省空间,可能增加扫描次数,影响查询性能 这些知识点涵盖了MySQL的基础概念、索引原理和优化策略,对于理解和...

    sql server中Select count(*)和Count(1)的区别和执行方式

    删除非聚集索引后,创建不同类型的索引(如在`ModifiedDate`上的DateTime索引和`StateProvinceID`上的INT索引),我们可以观察到SQL Server倾向于选择占用空间更小的索引,以减少IO操作,从而提高查询速度。...

    mysql面试题-关系模型

    - **OR 语句**中非索引列的使用。 10. **字符串索引策略**: - **完整索引**占用空间多,但查询效率高。 - **前缀索引**节省空间,但可能导致多次索引扫描,增加查询复杂度。 了解这些知识点有助于深入理解...

Global site tag (gtag.js) - Google Analytics