复合索引或多列索引,与单列索引相比,略显得复杂,对于复合索引,比较关心的是键列的次序,它决定了索引的排序,同时对SQL Server使用该索引来进行估计的查找谓词集合有一定的影响.
用一种简单的方法来说明这一问题就是使用电话本,电话本可能包括last_name,first_name列的索引.如果电话本的内容是按照last_name进行排序,要查找某个人的电话,只需知道last_name就可以轻松地找到该人,然而,如果我们仅知道该人的first_name,要找出符合该名的电话清单就是那么容易了,这就需要在first_name上进行排序的另一个电话本.
例如,在Col1和Col2列上有一个两列的索引,可以使用该索引来查找单列索引上的任何一个谓词,可以在以下谓词上进行查找:
Ø [Col1] = 3.14 AND [Col2] = 'pi'
Ø [Col1] = 'xyzzy' AND [Col2] <= 0
对于使用索引来满足col1列上的谓词,并非是col2列,在这些情况中,需要使用剩余谓词来查找:
Ø [Col1] > 100 AND [Col2] > 100
Ø [Col1] LIKE 'abc%' AND [Col2] = 2
不能使用索引来查找不在col1列上的谓词查找,则必须使用不同的索引来查找(也就是说以col2为第一个键列)或使用谓词扫描.
Ø [Col2] = 0
Ø [Col1] + 1 = 9 AND [Col2] BETWEEN 1 AND 9
Ø [Col1] LIKE '%abc' AND [Col2] IN (1, 3, 5)
标识索引键
在多数情况下,索引键通常是在CREATE INDEX语句中指定的列集合,当在含有聚集索引的表上创建非唯一的非聚集索引时,如果该索引并未显式说明非聚集索引键的部分时,需要将聚集索引键添加到非聚集索引键上.正如可以显式指定他们来查找这些隐式的键列一样.
覆盖列
对于堆或聚集索引的一张表,也叫"基表",包含(覆盖)了表的所有列,换句话说,非聚集索引只包含(覆盖)了表中的一小部分列,通过在非聚集索引来限制列的集合,SQL Server可以在每一页储存更多的行,这显然节约了空间,提高查找与扫描的效率,降低了I/O的操作数和页面数.然而,对于索引的扫描或查找来说,它只能返回该索引覆盖的那些列的记录行.
当创建覆盖列时,可以在非聚集索引上指定这些键列.如果基表是含有聚集索引的,位于该表上的每一个非聚集索引将覆盖聚集索引键,而不关心它们是否是非聚集索引键列的成员.在SQL Server 2005中,我们可以在非聚集索引上使用CREATE INDEX ...INCLUDE子语来添加额外的键列,注意:和索引键不同,INCLUDE中的列的次序并不重要.
下面我来通过一个示例说明,首先我们创建以下架构和对象:
CREATE TABLE T_heap (a int, b int, c int, d int, e int, f int)
CREATE INDEX T_heap_a ON T_heap (a)
CREATE INDEX T_heap_bc ON T_heap (b, c)
CREATE INDEX T_heap_d ON T_heap (d) INCLUDE (e)
CREATE UNIQUE INDEX T_heap_f ON T_heap (f)
CREATE TABLE T_clu (a int, b int, c int, d int, e int, f int)
CREATE UNIQUE CLUSTERED INDEX T_clu_a ON T_clu (a)
CREATE INDEX T_clu_b ON T_clu (b)
CREATE INDEX T_clu_ac ON T_clu (a, c)
CREATE INDEX T_clu_d ON T_clu (d) INCLUDE (e)
CREATE UNIQUE INDEX T_clu_f ON T_clu (f)
下面列举上面每一个索引的键列和覆盖列.
索引名称 |
键列 |
覆盖列 |
T_heap_a |
a |
a |
T_heap_bc |
b,c |
b,c |
T_heap_d |
d |
d,e |
T_heap_f |
f |
f |
T_clu_a |
a |
a,b,c,d,e,f |
T_clu_b |
b,a |
a,b |
T_clu_ac |
a,c |
a,c |
T_clu_d |
d,a |
a,d,e |
T_clu_f |
f |
a,f |
注意:对于T_clu表中的每一个非聚集索引键列均包含一个聚集索引键(T_clu_f除外,它是一个唯一索引).T_clu_ac显式包含了索引的第一个键,而其他的索引并无显式包含a列.
对于创建的列在实际的索引查找和书签查询是有何不同呢?
下面我们来看一个例子:
SELECT e from t_clu where b = 2
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/355374/viewspace-495809/,如需转载,请注明出处,否则将追究法律责任。