SQL Server 索引和表体系结构(三)
包含列索引
概述
包含列索引也是非聚集索引,索引结构跟聚集索引结构是一样,有一点不同的地方就是包含列索引的非键列只存储在叶子节点;包含列索引的列分为键列和非键列,所谓的非键列就是INCLUDE中包含的列,至少需要有一个键列,且键列和非键列不允许重复,非键列最多允许1023列(也就是表的最多列-1),由于索引键列(不包括非键)必须遵守现有索引大小的限制(最大键列数为 16,总索引键大小为 900 字节)的要求所以引进了包含列索引。
正文
- 创建包含列索引

----创建表
CREATE TABLE [dbo].[Customers](
[custid] [int] IDENTITY(1,1) NOT NULL,
[companyname] [nvarchar](40) NOT NULL,
[contactname] [nvarchar](30) NOT NULL,
[contacttitle] [nvarchar](400) NOT NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED
(
[custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] ----创建包含列索引
CREATE NONCLUSTERED INDEX [IX1_Customers] ON [dbo].[Customers]
(
[companyname] ASC
)
INCLUDE ( [contactname])
WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO 这里的键列就是:companyname
非键列就是:contactname
非键列具有下列优点:
- 它们可以是不允许作为索引键列的数据类型。
- 在计算索引键列数或索引键大小时,数据库引擎不考虑它们。

当查询中的所有列都作为键列或非键列包含在索引中时,带有包含性非键列的索引可以显著提高查询性能。这样可以实现性能提升,因为查询优化器可以在索引中找到所有列值;不访问表或聚集索引数据,从而减少磁盘 I/O 操作。(当索引包含查询引用的所有列时,它通常称为“覆盖查询”。)
- 创建覆盖查询
覆盖查询就是创建的索引列包含查询所引用的所有列时
- 查询列都设为键列

当我们的SELECT查询是这样的
SELECT
[companyname]
,[contactname]
,[contacttitle]
FROM [chenmh].[dbo].[Customers]
where companyname='好孩子' ---这时我们选择将索引列都包含在索引建列中
CREATE NONCLUSTERED INDEX [IX2_Customers] ON [dbo].[Customers]
( [companyname] ASC
,[contactname] ASC
,[contacttitle] ASC
)
WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO 将会弹出警告:警告! 最大键长度为 900 个字节。索引 'IX2_Customers' 的最大长度为 940 个字节。对于某些大值组合,插入/更新操作将失败。
由于三个字段都是NVARCHAR字段类型,每个字符需要 2 个字节,(40+30+400)*2=940个字节,大于900字节,这时我们可以将[contactname] ,[contacttitle]包含在非键列中

2.将大数据类型设为非键列

CREATE NONCLUSTERED INDEX [IX3_Customers] ON [dbo].[Customers]
( [companyname] ASC )
INCLUDE ( [contactname]
,[contacttitle])
WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO 这时索引键大小所占字符就只有40*2=80个字节,同时索引也是覆盖索引,索引的列包含查询用到的列,当我们查询数据时直接在索引页中查找数据就可以,不需要访问数据页,减少磁盘IO,提高性能

带有包含列的索引准则
设计带有包含列的非聚集索引时,请考虑下列准则:
- 在 CREATE INDEX 语句的 INCLUDE 子句中定义非键列。
- 只能对表或索引视图的非聚集索引定义非键列。
- 除 text、ntext 和 image 之外,允许所有数据类型。
- 精确或不精确的确定性计算列都可以是包含列。有关详细信息,请参阅为计算列创建索引。
- 与键列一样,只要允许将计算列数据类型作为非键索引列,从 image、ntext 和 text 数据类型派生的计算列就可以作为非键(包含性)列。
- 不能同时在 INCLUDE 列表和键列列表中指定列名。
- INCLUDE 列表中的列名不能重复。
列大小准则
- 必须至少定义一个键列。最大非键列数为 1023 列。也就是最大的表列数减 1。
- 索引键列(不包括非键)必须遵守现有索引大小的限制(最大键列数为 16,总索引键大小为 900 字节)。
- 所有非键列的总大小只受 INCLUDE 子句中所指定列的大小限制;例如,varchar(max) 列限制为 2 GB。
列修改准则
修改已定义为包含列的表列时,要受下列限制:
- 除非先删除索引,否则无法从表中删除非键列。
- 除进行下列更改外,不能对非键列进行其他更改:
- 将列的为空性从 NOT NULL 改为 NULL。
- 增加 varchar、nvarchar 或 varbinary 列的长度。
注意事项
- 键列的大小尽量小,有利用提高效率
- 将用于搜索和查找的列为键列,键列尽量不要包含没必要的列。(例如上面建立的覆盖查询列,虽然companyname+contactname加起来作为键列也不会超过900字节,但是这样键大小就变大了,降低了查询效率)
- 避免添加不必要的列。添加过多的索引列(键列或非键列)会对性能产生下列影响:
- 一页上能容纳的索引行将更少。这样会使 I/O 增加并降低缓存效率。
- 需要更多的磁盘空间来存储索引。特别是,将 varchar(max)、nvarchar(max)、varbinary(max) 或 xml 数据类型添加为非键索引列会显著增加磁盘空间要求。这是因为列值被复制到了索引叶级别。因此,它们既驻留在索引中,也驻留在基表中。
- 索引维护可能会增加对基础表或索引视图执行修改、插入、更新或删除操作所需的时间
总结
如果您觉得文章对你有帮助,活动活动你的手指麻烦给个推荐;这也是对我一种鼓励,在此表示感谢。
SQL Server 索引和表体系结构(三)的更多相关文章
- SQL Server 索引和表体系结构(聚集索引)
聚集索引 概述 关于索引和表体系结构的概念一直都是讨论比较多的话题,其中表的各种存储形式是讨论的重点,在各个网站上面也有很多关于这方面写的不错的文章,我写这篇文章的目的也是为了将所有的知识点尽可能的组 ...
- SQL Server 索引和表体系结构(一)
转自:http://www.cnblogs.com/chenmh/p/3780221.html 聚集索引 概述 关于索引和表体系结构的概念一直都是讨论比较多的话题,其中表的各种存储形式是讨论的重点,在 ...
- SQL Server 索引和表体系结构(非聚集索引)
非聚集索引 概述 对于非聚集索引,涉及的信息要比聚集索引更多一些,由于整个篇幅比较大涉及接下来的要写的“包含列的索引”,“索引碎片”等一些知识点,可能要结合起来阅读理解起来要更容易一些.非聚集索引和聚 ...
- SQL Server 索引和表体系结构(二)
转自:http://www.cnblogs.com/chenmh 非聚集索引 概述 对于非聚集索引,涉及的信息要比聚集索引更多一些,由于整个篇幅比较大涉及接下来的要写的“包含列的索引”,“索引碎片”等 ...
- SQL Server 索引和表体系结构(包含列索引)
包含列索引 概述 包含列索引也是非聚集索引,索引结构跟聚集索引结构是一样,有一点不同的地方就是包含列索引的非键列只存储在叶子节点:包含列索引的列分为键列和非键列,所谓的非键列就是INCLUDE中包含的 ...
- 7、SQL Server索引、表压缩
索引 什么是索引? 索引是一种磁盘上的数据结构,建立在表或视图的基础上.使用索引可以使数据的获取更快更高校,也会影响其他的一些性能,如插入或更新等. 索引主要分为两种类型:聚集索引和非聚集索引. 字典 ...
- SQL Server索引的维护 - 索引碎片、填充因子 <第三篇>
实际上,索引的维护主要包括以下两个方面: 页拆分 碎片 这两个问题都和页密度有关,虽然两者的表现形式在本质上有所区别,但是故障排除工具是一样的,因为处理是相同的. 对于非常小的表(比64KB小得多), ...
- 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效
数据库表设计时一对一关系存在的必要性 2017年07月24日 10:01:07 阅读数:694 在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都 ...
- sql server 索引总结三
一.非聚集索引维护 非聚集索引的行定位器值保持相同的聚集索引值,即使该聚集索引列物理上重新定位后,也是如此. 为了优化这个维护开销,SQL Server添加一个指向旧数据页的指针,以在页面分割之后指向 ...
随机推荐
- Java基础之读文件——使用通道读取混合数据1(ReadPrimesMixedData)
控制台程序,本例读取Java基础之写文件部分(PrimesToFile2)写入的Primes.txt. 方法一:可以在第一个读操作中读取字符串的长度,然后再将字符串和二进制素数值读入到文本中.这种方式 ...
- tomcat deploy部署项目三种方法
1.将应用文件夹或war文件直接copy到tomcat的webapps目录下,这样tomcat启动的时候会将webapps目录下的文件夹或war文件的内容当成应用部署.这种方式最简单且无须书写任何配置 ...
- Swift动画编程指南-02 Swift动画是怎么炼成的
上一节我们看了几个很棒的例子,我们不禁会想.他们是怎么设计的,怎么从一个空白的画布变成一个完整的,美丽的动画.这些动画是如何产生的,是哪些属性被改变了.我们还要认真思考的是,每一个步骤到底发生了什么. ...
- SQL语句执行时间测试
select getdate()--开始执行时间 要执行的SQL语句 select getdate() --结束时间
- Codeforce Round #213 Div2
哎,弄了半天这次的C还是没出,真是捉急!,还TM的以为前几次只是运气不好!太逗了!
- using 名称空间指定一个别名
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- HDU 2993 MAX Average Problem(斜率优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 Problem Description Consider a simple sequence w ...
- paper 7:支持向量机系列四:Outliers —— 介绍支持向量机使用松弛变量处理 outliers 方法。
在最开始讨论支持向量机的时候,我们就假定,数据是线性可分的,亦即我们可以找到一个可行的超平面将数据完全分开.后来为了处理非线性数据,使用 Kernel 方法对原来的线性 SVM 进行了推广,使得非线性 ...
- 夺命雷公狗ThinkPHP项目之----企业网站29之网站前台左侧导航的高亮显示
其实这里就是加多一段jq代码即可: 首先加一个id : 然后在下面加多一段jq代码即可: <script type="text/javascript"> $(docum ...
- Arm环境搭建-基于博创科技(CentOS7.0系统安装篇1)
CentOs 7.0安装和基本命令篇 目的:学习基本的linux命令,熟悉linux操作系统,安装linux.(安装过5.5,6.3并不是安装一帆风顺的,多次安装,有个10次多吧,基本会 ...