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

  然而,以上这不是我想要传达的全部意思,因为他不仅仅是避免逻辑或物理的读取的问题。在“非聚集索引”中的列和需要在表中查找的列之间,还需要考虑“将数据放在一起”的必要工作。为了说明这个问题,让我们创建两个完全一模一样的表,即:相同的结构,相同的数据且都是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. Java-马士兵设计模式学习笔记-装饰者模式

    Java装饰者模式简介 一.假设有一个Worker接口,它有一个doSomething方法,Plumber和Carpenter都实现了Worker接口,代码及关系如下: 1.Worker.java p ...

  2. hdu6331 Problem M. Walking Plan

    传送门 题目大意 给你一个n点m条边的有向图,q次询问,给定s,t,k,求由s到t至少经过k条边的最短路. 分析 我们设dp[i][j][k]为从i到j至少经过k条边的最短路,sp[i][j]意为从i ...

  3. Mysql--连接查询

    内连接查询 意义:找到表和表之间的关系或者是桥梁.连接查询是查询两个或者两个以上的表时使用的. JOIN|CROSS JOIN| INNER JOIN    通过ON  连接条件(这三个方式都行)一般 ...

  4. C++笔记--指针数组和结构

    指针 类型为T*的变量能保存一个类型T对象的地址 Char c=‘a’:Char * p=& c://保存了c的地址 指针的操作一般都是间接的引用,就是相当于引用指针所指的对象. 0是一个特殊 ...

  5. 【Android学习】三种布局<include />、<merge />、<ViewStub />

    1.布局重用<include /> <include />标签能够重用布局文件,使用起来非常简单 <include layout="@layout/layout ...

  6. 解决Spring MVC 对AOP不起作用的问题

    用的是 SSM3的框架 Spring MVC 3.1 + Spring 3.1 + Mybatis3.1 第一种情况: Spring MVC 和 Spring 整合的时候,SpringMVC的spri ...

  7. python 根据字典中的key,value进行排序

    #coding=utf-8 import requests,json,collections,base64,datetime def sort(datas): data=json.dumps(data ...

  8. PostgreSQL 设置主键的序列值

    1. 问题的提出 PostgreSQL定义TABLE时,主键的字段类型可以设定为自增类型serial,即插入每条记录时,主键的值自动加1.但是,当插入数据的时候指定了具体的主键值,例如主键值从0到50 ...

  9. Spring Boot 学习系列(05)—自定义视图解析规则

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 自定义视图解析 在默认情况下Spring Boot 的MVC框架使用的视图解析ViewResolver类是C ...

  10. Struct结构体

    1.结构体的定义与调用 // 定义结构体类型 // 结构体类型名为 MyDate1 struct MyDate1 { int year; int month; int day; }; // 定义结构体 ...