当数据库设计遇到非聚集索引超出 SQLServer 限制的索引最大长度 (列数最大 16,长度最大 900 字节) 时,通过包含非键列,可以创建覆盖更多查询的非聚集索引。
书写格式为:Create nonclustered Index IndexName on TableName (KeyColumes) include (NonKeyColumes)
例如:
为用户表 Users 中的Name nvarchar(50),Code varchar(50), description nvarchar(1000)
的三列创建非聚集索引,因为 description 列超出常规索引长度限制,则使用 include 语句将 description 添加至索引非键列。
即: create nonclustered index Users1 on Users (Name,Code) include (description) 。
1、至少有一个键列,非键列最大列数为 1023(表最大列数-1)。
2、只能用于非聚集索引。
3、允许使用除 text、ntext、image 外的其他所有数据类型。
4、不能同时在键列和 include 列表中指定同一列名。
5、键列仍受索引最大长度限制。
6、非键列修改时同索引键列一样收到限制,若未删除索引,则无法修改非键列。
【索引覆盖】: 如果返回的数据列就包含于索引的键值中,或者包含于索引的键值 + 聚集索引的键值中,那么就不会发生 Bookmark Lookup(通过行定位器进行数据查找的检索方式),因为找到索引项,就已经找到所需的数据了,没有必要再到数据行去找了。这种情况,叫做索引覆盖。索引覆盖的查询性能大于其他所有情况。(返回数据行数较多时也将大于聚集索引) 【非键列】: 键列就是在索引中所包含的列,当然非键列就是该索引之外的列了。
为在设计中尽可能达到索引覆盖,应合理进行表索引设计。但很多时候,数据表中列的大小多列组合大小大于 900 字节。故在 SQL Server 2005 及其之后版本中,可以通过将非键列添加到非聚集索引的叶级别来扩展非聚集索引的功能。通过包含非键列,可以创建覆盖更多查询的非聚集索引。
!但是,Gul’dan,代价是什么呢。
A、include 可以包含大量列,但这些列不能作为键使用!也就是说,不可以作为查询语句中的 where 条件项来使用。否则仍然进行原始表查询,失去了该索引的意义。
B、添加过多的非键列 (键列) 仍旧会对性能造成影响,原因是索引过长,单页容纳索引行变少,降低缓存效率。
C、需要更大的磁盘空间存储索引,这是因为列值被复制到了索引叶级别。
更新:
不能在具有唯一索引的对象中插入重复键的行
,都怪平时没好好看错误提示。人家说的清楚,只跟键有关,所以 create unique nonclustered 索引,unique 只限制 include 之前的键列。
Over