sqlserver中复合索引和include索引到底有多大区别?

一:从数据页角度看问题

1. 做两个表,插入两条数据,在test1上做复合索引,在test2上做include索引,如下图:

复制代码
 1 -- 在test1表中插入2条记录
 2 CREATE TABLE test1(ID int,Name CHAR(5),Email CHAR(10))
 3 INSERT INTO test1 VALUES(1,'aaaaa','111@qq.com')
 4 INSERT INTO test1 VALUES(2,'bbbbb','222@qq.com')
 5 CREATE INDEX idx_test1 ON dbo.test1(Name,Email)
 6 
 7 -- 在test2表中插入2条记录
 8 CREATE TABLE test2(ID int,Name CHAR(5),Email CHAR(10))
 9 INSERT INTO test2 VALUES(1,'aaaaa','111@qq.com')
10 INSERT INTO test2 VALUES(2,'bbbbb','222@qq.com')
11 CREATE INDEX idx_test2 ON dbo.test2(Name) INCLUDE(Email)
复制代码

 

2. 然后通过DBCC 命令查看数据页记录

<1> 先来看看test1表中各个槽位的信息

1 DBCC TRACEON(2588,3604)
2 DBCC IND(Ctrip,test1,-1)
3 DBCC PAGE(Ctrip,1,194,1) 
复制代码
 1 Slot 0, Offset 0x60, Length 27, DumpStyle BYTE
 2 
 3 Record Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP     Record Size = 27
 4 
 5 Memory Dump @0x000000000FB0A060
 6 
 7 0000000000000000:   16616161 61613131 31407171 2e636f6d †.aaaaa111@qq.com 
 8 0000000000000010:   c0000000 01000000 030000†††††††††††††...........      
 9 
10 Slot 1, Offset 0x7b, Length 27, DumpStyle BYTE
11 
12 Record Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP     Record Size = 27
13 
14 Memory Dump @0x000000000FB0A07B
15 
16 0000000000000000:   16626262 62623232 32407171 2e636f6d †.bbbbb222@qq.com 
17 0000000000000010:   c0000000 01000100 030000†††††††††††††...........      
18 
19 OFFSET TABLE:
20 
21 Row - Offset                         
22 1 (0x1) - 123 (0x7b)                 
23 0 (0x0) - 96 (0x60)            
复制代码

 

<2> 再来看看test2表中各个槽位信息

1 DBCC TRACEON(2588,3604)
2 DBCC IND(Ctrip,test2,-1)
3 DBCC PAGE(Ctrip,1,207,1)
复制代码
 1 Slot 0, Offset 0x60, Length 27, DumpStyle BYTE
 2 
 3 Record Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP     Record Size = 27
 4 
 5 Memory Dump @0x000000000DFCA060
 6 
 7 0000000000000000:   16616161 6161c400 00000100 00003131 †.aaaaa........11 
 8 0000000000000010:   31407171 2e636f6d 030000†††††††††††††1@qq.com...      
 9 
10 Slot 1, Offset 0x7b, Length 27, DumpStyle BYTE
11 
12 Record Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP     Record Size = 27
13 
14 Memory Dump @0x000000000DFCA07B
15 
16 0000000000000000:   16626262 6262c400 00000100 01003232 †.bbbbb........22 
17 0000000000000010:   32407171 2e636f6d 030000†††††††††††††2@qq.com...      
18 
19 OFFSET TABLE:
20 
21 Row - Offset                         
22 1 (0x1) - 123 (0x7b)                 
23 0 (0x0) - 96 (0x60) 
复制代码

 

<3> 从test1和test2的数据页来看,都是有两个slot槽位,然后我们把test1和test2的slot0槽位拿出来对比下,是不是就知道两者大概有什么区别了。

test1のslot0 

1 0000000000000000:   16616161 61613131 31407171 2e636f6d †.aaaaa111@qq.com 
2 0000000000000010:   c0000000 01000000 030000†††††††††††††...........    

test2のslot0 

1 0000000000000000:   16616161 6161c400 00000100 00003131 †.aaaaa........11 
2 0000000000000010:   31407171 2e636f6d 030000†††††††††††††1@qq.com...     

下面我仔细解剖下两表中的slot内容:

 16   6161616161   3131314071712e636f6d  c0000000 0100 0000  0300    00

16:                              这个是索引记录的系统头数据。

6161616161:               转换成十进制就是9797979797,也就是字符的aaaaa。

3131314071712e636f6d:  这个我想你也懂,也就是111@qq.com。

c000000010000000:        因为我们是堆表,所以这个就是表的RowID,转化为十进制就是: 192:1:0。

0300:                            这个表示表中的记录数,也就是3条记录。

 

如果你对上面的讲解明白了,那我们继续看看test2のslot0,如果你仔细的话,你会看到在test2中,111qq.com是在记录的最后。。。那这说明什

问题呢???如果你对记录比较熟悉的话,你就知道,其实记录中的变长字段值一般都是放在记录的尾部。。。好处就是可以做到“行溢出”。也就是

可以超过索引的900长度限制。。。而复合索引却无法做到。。。如果你不信我可以做个例子,将name和email的长度设为定长500。

 

而include索引却可以顺利通过。。。。。

聚簇索引和非聚簇索引SQL Server数据库用于提高查询效率的两种不同类型的索引。它们的主要区别在于数据的存储方式以及它们与数据表的物理顺序的关联程度。 聚簇索引:聚簇索引决定了数据在表的物理存储顺序,因此每个表只能有一个聚簇索引。聚簇索引的叶节点就是数据页,数据行就是按索引键的顺序存储的。当创建聚簇索引时,数据行会被重新排列,使其与索引的顺序相匹配。这意味着,如果表上有聚簇索引,那么数据的物理顺序和索引顺序是相同的。聚簇索引对查询性能影响最大的操作是范围查询,因为相关数据在物理上是连续存储的,所以读取速度快。 非聚簇索引:非聚簇索引则拥有与聚簇索引不同的物理排序顺序,它有自己的索引结构,每个表可以有多个非聚簇索引。非聚簇索引的叶节点包含索引键值和指向数据行的指针。由于数据行并没有根据非聚簇索引排序,所以当你使用非聚簇索引进行查询时,数据库系统可能需要进行额外的查找来获取完整的数据行。非聚簇索引适用于查询经常使用的列,但这些列不是表的主键。 总结两者的区别如下: 1. 物理存储:聚簇索引决定了数据表的物理排序顺序,非聚簇索引则使用单独的索引结构,并不改变数据行的物理存储顺序。 2. 索引结构:聚簇索引的叶节点直接包含数据行,非聚簇索引的叶节点包含指向数据行的指针和索引列的值。 3. 性能影响:聚簇索引对范围查询和排序操作影响较大,非聚簇索引对于单个查询条件的查找效率影响较大。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值