SQL Server覆盖索引--有无包含列对数据库查询性能的影响分析
“覆盖索引使您能够避免返回到表中以满足请求的所有列,因为所有请求的列都已经存在于非聚集索引中。这意味着您还可以避免返回到表中进行任何逻辑或物理的信息读取。”
然而,以上这不是我想要传达的全部意思,因为他不仅仅是避免逻辑或物理的读取的问题。在“非聚集索引”中的列和需要在表中查找的列之间,还需要考虑“将数据放在一起”的必要工作。为了说明这个问题,让我们创建两个完全一模一样的表,即:相同的结构,相同的数据且都是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条记录。唯一的不同就是他们单一的非聚集索引,一个有包含列,另一个没有包含列。他们还有完全一样的主键及聚集索引。
如果我在有包含列的表上提交以下的查询,我们会看到以下的执行计划:
FROM Cruiser_1
WHERE last_name = 'Jones' AND first_name = 'Mary';
上述操作都发生在非聚集索引的内部。我们也不需要回到表上获取更多的数据。如果我们执行完全一样的查询在具有同样索引结构的表上,在非聚集索引列除去了包含列,我们得到了不同的行为:
FROM Cruiser_2
WHERE last_name = 'Jones' AND first_name = 'Mary';
因为上述的非聚集索引并没有包含我们所需的所有信息来满足当前的查询,所以它有必要针对索引来获取基本信息,并且在非聚集索引上使用行指针,从表中获取registration_id并且运行一个嵌套循环,其目的是为了使两组工作数据在返回给终端用户之前结合在一起。针对上述查询,我们可以通过查看I/O统计来发现消耗在数据读取上不同的开销:
请注意,这些都是逻辑读取,因为页面已经在缓冲区中。如果有这么一个情况,它是一个更大的数据集,如果你想要使用的页面仍然在活动服务器的磁盘上,这可能一个非常昂贵的操作。
我希望上述操作能更好地描述了我的观点! 附:原文链接!
SQL Server覆盖索引--有无包含列对数据库查询性能的影响分析的更多相关文章
- Sql Server 覆盖索引
覆盖索引通常都是复合索引,即索引字段为多个.创建索引时应该注意索引排列顺序. Sql Server检索应用索引时,字段识别顺序为 从左到右. 例如如下索引的使用上 Create NONCLUSTERE ...
- SQL Server中多表连接时驱动顺序对性能的影响
本文出处:http://www.cnblogs.com/wy123/p/7106861.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- SQL Server如何在变长列上存储索引
这篇文章我想谈下SQL Server如何在变长列上存储索引.首先我们创建一个包含变长列的表,在上面定义主键,即在上面定义了聚集索引,然后往里面插入80000条记录: -- Create a new t ...
- SQL Server 2016新特性:列存储索引新特性
SQL Server 2016新特性:列存储索引新特性 行存储表可以有一个可更新的列存储索引,之前非聚集的列存储索引是只读的. 非聚集的列存储索引支持筛选条件. 在内存优化表中可以有一个列存储索引,可 ...
- 【译】索引进阶(八):SQL SERVER唯一索引
[译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正] 原文链接:传送门. 在本章节我们检查唯一索引.唯一索引的特别之处在于它不仅提供了性能益处,而且提供了数据完整性益处.在SQL SER ...
- SQL Server 查询优化 索引的结构与分类
一.索引的结构 关系型数据库中以二维表来表达关系模型,表中的数据以页的形式存储在磁盘上,在SQL SERVER中,数据页是磁盘上8k的连续空间,那么,一个表的所有数据页在磁盘上是如何组织的呢?分两种情 ...
- SQL Server创建索引(转)
什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的速度,汉语字(词)典一般都有按拼音. ...
- 理解SQL Server中索引的概念
T-SQL查询进阶--理解SQL Server中索引的概念,原理以及其他 简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,SQL Server仍然可以实现应有的功能 ...
- SQL Server创建索引
原文:SQL Server创建索引 什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的 ...
随机推荐
- 算法Sedgewick第四版-第1章基础-018一解决不能声明泛型数组的两咱方法(强转或反射)
1. /****************************************************************************** * Compilation: ja ...
- Luogu 4206 [NOI2005]聪聪与可可
BZOJ 1415 简单期望 + 记忆化搜索. 发现聪聪每一步走向的地方是在可可的所在位置确定时是确定的,设$nxt_{x, y}$表示聪聪在$x$,可可在$y$时聪聪下一步会走到哪里,我们先预处理出 ...
- python3-file的修改实现类似shell中sed的功能
# Auther: Aaron Fan '''思路:目的是为了修改yesterday这个文件,但是因为无法直接去修改这个文件,所以需要先把修改好的内容写入高yesterday.new这个文件中,然后再 ...
- Entity Framework Tutorial Basics(39):Raw SQL Query
Execute Native SQL Query You can execute native raw SQL query against the database using DBContext. ...
- Java Collection.RP
在 Java2中,有一套设计优良的接口和类组成了Java集合框架Collection,使程序员操作成批的数据或对象元素极为方便.这些接口和类有很多对抽象数据类型操作的API,而这是我们常用的且在数据结 ...
- STL 堆的使用
本来是要写leetcode上的merge k sorted lists那道题目,这个题目我还是很熟悉的,毕竟是看过算法导论的人,但是写的过程中对堆的维护代码还是挺多的,所以我想到了STL中的堆.下面就 ...
- C#使用SendMessage实现进程间通信的方法
本文实例讲述了C#使用SendMessage实现进程间通信的方法.分享给大家供大家参考.具体分析如下: 为了深入理解消息机制,先来做一个测试项目 在新建项目的Form1的代码中,加入方法: ? 1 2 ...
- AtCoder Grand Contest 011D(思维,规律,异或)
#include<bits/stdc++.h>using namespace std;char s[200007];int ans[200007];int main(){ int n ...
- Java框架之搭建环境maven报错
*maven Dependencies 中的地址通过POM 才会增加 正确是 1. m2所在位置 遇到的问题: java.lang.ClassNotFoundException: org.spring ...
- Python之‘’控制流‘’
一.if语句 格式: i1 = 3 if i1 > 4: print('yes you are right') elif 0 < i1 < 4: print('im dont kon ...