设为首页 收藏本站
查看: 1227|回复: 0

[经验分享] Sql Server之旅——第八站 复合索引和include索引到底有多大区别?

[复制链接]

尚未签到

发表于 2015-6-27 16:38:32 | 显示全部楼层 |阅读模式
    周末终于搬进出租房了,装了宽带。。。。才发现没网的日子。。。那是一个怎样的与世隔绝呀。。。再也受不了那样的日子了。。。。好了,既然网
  安上去了,还得继续我的这个系列。
    索引和锁,这两个主题对我们开发工程师来说,非常的重要。。。只有理解了这两个主题,我们才能写出高质量的sql语句,在之前的博客中,我所说的
  索引都是单列索引。。。当然数据库不可能只认单列索引,还有我这篇的复合索引,说到复合索引,可能熟悉的人又会说到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 命令查看数据页记录
   先来看看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)            
  
   再来看看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)
  
   从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。
   DSC0000.png
  
  而include索引却可以顺利通过。。。。。
  
  
  这几天上海特别冷,打字都打着手哆嗦。。。不准备继续说了。。。下一篇继续扯下复合索引到底都能带来哪些好处。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-81007-1-1.html 上篇帖子: SQL Server数据库的备份与还原(.NET项目) 下篇帖子: SQL Server 错误日志过滤(ERRORLOG)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表