一、 几个概念
- 覆盖索引
返回的数据列就包含于索引的键值中,或者包含于索引的键值+聚集索引的键值中,那么就不会发生Bookup Lookup,因为找到索引项,就已经找到所需的数据了,没有必要再到数据行去找了。 - 复合索引
复合索引就是包含两个或者多个字段的索引 - 非键列
键列就是在索引中所包含的列,当然非键列就是该索引之外的列了
二、2005的新特性
在 SQL Server 2005 中,可以通过将非键列添加到非聚集索引的叶级别来扩展非聚集索引的功能。通过包含非键列,可以创建覆盖更多查询的非聚集索引。这是因为非键列具有下列优点:
- 它们可以是不允许作为索引键列的数据类型。
- 在计算索引键列数或索引键大小时,数据库引擎不考虑它们。
即:索引包含列不受900字节、最多16个键列以及部分无法在大类型数据列如(varchar(max))上创建键列的限制
当查询中的所有列都作为键列或非键列包含在索引中时,带有包含性非键列的索引可以显著提高查询性能。因为查询优化器可以在索引中找到所有列值;不访问表或聚集索引数据,从而减少磁盘 I/O 操作。
三、设计准则
- 在 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 列的长度。
六、设计建议
重新设计索引键大小较大的非聚集索引,以便只有用于搜索和查找的列为键列。将覆盖查询的所有其他列设置为包含性非键列。这样,将具有覆盖查询所需的所有列,但索引键本身较小,而且效率高。
七、性能注意事项
避免添加不必要的列。添加过多的索引列(键列或非键列)会对性能产生下列影响:
- 一页上能容纳的索引行将更少。这样会使 I/O 增加并降低缓存效率。
- 需要更多的磁盘空间来存储索引。特别是,将 varchar(max)、nvarchar(max)、varbinary(max) 或 xml 数据类型添加为非键索引列会显著增加磁盘空间要求。这是因为列值被复制到了索引叶级别。因此,它们既驻留在索引中,也驻留在基表中。
- 索引维护可能会增加对基础表或索引视图执行修改、插入、更新或删除操作所需的时间。
应该确定修改数据时在查询性能上的提升是否超过了对性能的影响,以及是否需要额外的磁盘空间要求。有关评估查询性能的详细信息,请参阅查询优化。
参考:
https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2005/ms190806%28v%3dsql.90%29
http://www.cnblogs.com/gaizai/archive/2010/01/11/1644358.html
为什么include列可以超过900字节限制
https://www.cnblogs.com/huangxincheng/p/4266479.html