“覆盖索引使您能够避免返回到表中以满足请求的所有列,因为所有请求的列都已经存在于非聚集索引中。这意味着您还可以避免返回到表中进行任何逻辑或物理的信息读取。”

  然而,以上这不是我想要传达的全部意思,因为他不仅仅是避免逻辑或物理的读取的问题。在“非聚集索引”中的列和需要在表中查找的列之间,还需要考虑“将数据放在一起”的必要工作。为了说明这个问题,让我们创建两个完全一模一样的表,即:相同的结构,相同的数据且都是10000条:

CREATE TABLE Beach.dbo.cruiser_1
(
pkid INT IDENTITY(1,1) NOT NULL,
registration_id VARCHAR(20) NOT NULL,
last_name VARCHAR(50) NOT NULL,
first_name VARCHAR(50) NOT NULL,
address_1 VARCHAR(100) NULL,
address_2 VARCHAR(100) NULL,
city VARCHAR(100) NULL,
state_region VARCHAR(100) NULL,
postal_code VARCHAR(10) NULL,
company_id VARCHAR(20) NULL,
plus_one_notes VARCHAR(200) NULL,
registration_notes VARCHAR(200) NULL
); CREATE TABLE Beach.dbo.cruiser_2
(
pkid INT IDENTITY(1,1) NOT NULL,
registration_id VARCHAR(20) NOT NULL,
last_name VARCHAR(50) NOT NULL,
first_name VARCHAR(50) NOT NULL,
address_1 VARCHAR(100) NULL,
address_2 VARCHAR(100) NULL,
city VARCHAR(100) NULL,
state_region VARCHAR(100) NULL,
postal_code VARCHAR(10) NULL,
company_id VARCHAR(20) NULL,
plus_one_notes VARCHAR(200) NULL,
registration_notes VARCHAR(200) NULL
);

  请相信我,两个表中的数据是完全一样的。在此我们就暂时不把每个表10000条的数据展示了。同时,我已经在每个表上创建了完全一样的两个聚集索引,且都在pkid列上,

因为该列为自动增长列,我也把pkid列上的填充因子设置为了100%.

 ALTER TABLE dbo.cruiser_1 ADD CONSTRAINT
PK_cruiser_1_pkid PRIMARY KEY CLUSTERED
(
pkid
)
WITH
(
PAD_INDEX = OFF
, FILLFACTOR = 100
, STATISTICS_NORECOMPUTE = OFF
, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]; GO ALTER TABLE dbo.cruiser_2 ADD CONSTRAINT
PK_cruiser_1_pkid PRIMARY KEY CLUSTERED
(
pkid
)
WITH
(
PAD_INDEX = OFF
, FILLFACTOR = 100
, STATISTICS_NORECOMPUTE = OFF
, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]; GO

  最后,让我们在两个表之间引入一些不同的东西。dbo.cruiser_1是一个建立在 last_name和first_name列且具有包含列registration_id的非聚集索引.dbo.cruiser_2是与索引dbo.cruiser_1相同的非聚集索引但没有包含列,如下所示.

CREATE NONCLUSTERED INDEX [IX_cruiser_1_last_name] ON [dbo].[cruiser_1]
(
[last_name] ASC,
[first_name] ASC
)
INCLUDE
(
[registration_id]
)
WITH
(
PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, SORT_IN_TEMPDB = OFF
, DROP_EXISTING = OFF
, ONLINE = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON
, FILLFACTOR = 80
)
GO CREATE NONCLUSTERED INDEX [IX_cruiser_2_last_name] ON [dbo].[cruiser_2]
(
[last_name] ASC,
[first_name] ASC
)
WITH
(
PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, SORT_IN_TEMPDB = OFF
, DROP_EXISTING = OFF
, ONLINE = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON
, FILLFACTOR = 80
)
GO

  让我们重新回顾一下:我们有两个完全一样的table,每个表都有10000条记录。唯一的不同就是他们单一的非聚集索引,一个有包含列,另一个没有包含列。他们还有完全一样的主键及聚集索引。

  如果我在有包含列的表上提交以下的查询,我们会看到以下的执行计划:

  SELECT [registration_id], last_name, first_name 
  FROM Cruiser_1 
  WHERE last_name = 'Jones' AND first_name = 'Mary';
  

  上述操作都发生在非聚集索引的内部。我们也不需要回到表上获取更多的数据。如果我们执行完全一样的查询在具有同样索引结构的表上,在非聚集索引列除去了包含列,我们得到了不同的行为:

  SELECT [registration_id], last_name, first_name 
  FROM Cruiser_2 
  WHERE last_name = 'Jones' AND first_name = 'Mary';
  

  因为上述的非聚集索引并没有包含我们所需的所有信息来满足当前的查询,所以它有必要针对索引来获取基本信息,并且在非聚集索引上使用行指针,从表中获取registration_id并且运行一个嵌套循环,其目的是为了使两组工作数据在返回给终端用户之前结合在一起。针对上述查询,我们可以通过查看I/O统计来发现消耗在数据读取上不同的开销:

  请注意,这些都是逻辑读取,因为页面已经在缓冲区中。如果有这么一个情况,它是一个更大的数据集,如果你想要使用的页面仍然在活动服务器的磁盘上,这可能一个非常昂贵的操作。

  我希望上述操作能更好地描述了我的观点!  附:原文链接

SQL Server覆盖索引--有无包含列对数据库查询性能的影响分析的更多相关文章

  1. Sql Server 覆盖索引

    覆盖索引通常都是复合索引,即索引字段为多个.创建索引时应该注意索引排列顺序. Sql Server检索应用索引时,字段识别顺序为 从左到右. 例如如下索引的使用上 Create NONCLUSTERE ...

  2. SQL Server中多表连接时驱动顺序对性能的影响

    本文出处:http://www.cnblogs.com/wy123/p/7106861.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  3. SQL Server如何在变长列上存储索引

    这篇文章我想谈下SQL Server如何在变长列上存储索引.首先我们创建一个包含变长列的表,在上面定义主键,即在上面定义了聚集索引,然后往里面插入80000条记录: -- Create a new t ...

  4. SQL Server 2016新特性:列存储索引新特性

    SQL Server 2016新特性:列存储索引新特性 行存储表可以有一个可更新的列存储索引,之前非聚集的列存储索引是只读的. 非聚集的列存储索引支持筛选条件. 在内存优化表中可以有一个列存储索引,可 ...

  5. 【译】索引进阶(八):SQL SERVER唯一索引

    [译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正] 原文链接:传送门. 在本章节我们检查唯一索引.唯一索引的特别之处在于它不仅提供了性能益处,而且提供了数据完整性益处.在SQL SER ...

  6. SQL Server 查询优化 索引的结构与分类

    一.索引的结构 关系型数据库中以二维表来表达关系模型,表中的数据以页的形式存储在磁盘上,在SQL SERVER中,数据页是磁盘上8k的连续空间,那么,一个表的所有数据页在磁盘上是如何组织的呢?分两种情 ...

  7. SQL Server创建索引(转)

    什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的速度,汉语字(词)典一般都有按拼音. ...

  8. 理解SQL Server中索引的概念

    T-SQL查询进阶--理解SQL Server中索引的概念,原理以及其他   简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,SQL Server仍然可以实现应有的功能 ...

  9. SQL Server创建索引

    原文:SQL Server创建索引 什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的 ...

随机推荐

  1. C语言-郝斌笔记-006排序及查找

    1. int partion(int *a, int low, int high) { int value = a[low]; int t; while (low < high) { while ...

  2. python3-字典中存储列表

    # Auther: Aaron Fan #示例1:#存储所点披萨的信息pizza = { '外皮':'厚的', '配料列表':['香菇', '奶酪'],}#概述所点的比萨print('您点了一道&qu ...

  3. maven tomcat:run指定tomcat7:

    配置好下面的内容后,执行 run as -> tomcat7:run 或者tomcat6:run可以将maven的web应用在tomcat6/7里面运行 ,eclipse Indigo 版本默认 ...

  4. python常见的加密解密

    #!/usr/bin/env python ''' Python Crypto Wrapper - By Chase Schultz Currently Supports: AES-256, RSA ...

  5. 网站下载器WebZip、Httrack及AWWWB.COM网站克隆器

     动机 闲扯节点,可略读. 下载并试用这些软件并非是为了一己之私,模仿他人网站以图利.鉴于国内网络环境之艰苦,我等屌丝级半罐水程序员,纵有百度如诸葛大神万般协力相助,也似后主般无能不能解决工作和娱乐中 ...

  6. 【Arcgis android】 离线编辑实现及一些代码段

    Arcgis android 离线编辑实现及一些代码段 底图添加 private String path="file:///mnt/sdcard/data/chinasimple.tpk&q ...

  7. Referenced file contains errors (http://www.springframework.org/schema/beans/spring-beans-3.1.xsd)

    解决方法: 将 Preferences > XML > XML Files > Validation中"Honour all XML schema locations&qu ...

  8. Java为何这么难学?

    在学校的时候,就开始接触Java,哪个时候学的是基础的语法.毕业之后,由于没有找到实习工作且没有从事Java开发,慢慢的就把Java给丢了.从学校出来的几个同事,有的进入了项目实施行业,做了项 目经理 ...

  9. MAC的开机启动

    之前了解到MAC下的开机启动和定时自动运行不再沿用cron,而是有自己的launchctl:把启动文件放在/Library/LaunchDaemon/xxx.plist,里面可以记录运行的时间间隔.工 ...

  10. iOS中Info.plist文件的常见配置

    . 在创建一个新的Xcode工程后,会 在Supporting Files文件夹下自动生成一个工程名-Info.plist的文件,这个是对工程做一些运行期配置的文件(很重要,必须有该文件). 如果使用 ...