说到聚集索引,我想每个码农都明白,但是也有很多像我这样的伪程序员,只能用死记硬背来解决这个问题,什么表中只能建一个聚集索引,然后又扯到了目录查找来帮助读者记忆。。。。问题就在这里,我们不是学文科,,,不需要去死记硬背,,,我们需要的就是能看到在眼里面的 真实东西。。。。。我们都喜欢聚集索引,因为它能够把无序的堆表记录变成有序,还玩起了B树。。。这样就把复杂度从N降低到了LogMN。。。这样的话逻辑读,物理读就下来了。

一:现象

1:无索引的情况

还是老规矩,看个例子感受下,首先我有一个Product表,里面没有任何索引,如下图:

从上图中,我悲剧的看到了,物理读是9次,也就说明走了9次硬盘,你也可以想到,走硬盘的目的是为了拿数据,逻辑读有1636次,要注意的是这里的”次“是“页”的意思,也就是在内存中走了1636个数据页,我用dbcc ind 给你看一下,是不是有1636个表数据页。

这里有1637个数据页的原因是第一个是IAM跟踪页。

2:有聚集索引的情况

下面我在Product表中建一个product_idx_productid的聚集索引,然后再次看看io情况,如下图:

当你看到这个”逻辑读“为3次的时候,你是不是已经疯了。。。在多达1636个数据页中找到目标数据,只需3次。。。。这个在算法盲看来是不是神仙下凡???当然,,,此物天上有,人间也有。。。既然有,就应该有一种非常强烈的探索欲。。。。看看这里面到底是怎么玩的。。。。。。

二:探索原理

1:探索叶子节点

刚才也说了,聚集索引玩的就是B树,既然是B树,那就有叶子节点和分支节点,专业术语就是度为0的为叶子节点,度>0的叫做分支节点。。。。我想你也听说了,聚集索引是将索引列数据进行排序后放入B树,那为了让你眼见为实,我先建立一个ID无序的3条记录。


insert into Person values(2,'bbbbb')
insert into Person values(3,'ccccc')
insert into Person values(1,'aaaaa')

然后我用dbcc ind 命令查看下3条记录在哪个数据页中,如图:

从图中可以看到,我的三条记录是放在148号数据页中的,然后我导出148号数据页,看看内容是什么。


dbcc traceon(3604)
dbcc page(Ctrip,1,148,1)

从上图中,我们看到了”数据页“中的各个槽位的指向是按照表中的实际存储记录来的,好了,下面我创建个聚集索引,看看实际数据是不是真的有序了?


create clustered index Ctrip_idx_ID on Person(ID)

不过在这里有个有趣的问题,我的148号”表数据页“哪去了???也是够奇葩的,换来的确实173号索引页,那为了保证数据完整性,应该是把 148号数据页的内容灌到173索引页里面去了吧????没关系,验证一下。


dbcc traceon(3604)
dbcc page(Ctrip,1,173,1)

通过上面的图,有没有直观的感觉到?数据现在已经是aaaaa,bbbbb,ccccc的模式了。。。有序啦。。。。同时索引页中也保存了148号数据页的字段值,比如ID,Name信息,拿下面的slot0槽位举例:

到此为止,我想你对叶子节点的内容有了个大概的认识,起码没有让你死记硬背了~~~

2 :探索分支节点

为了让你看到分支节点,我得多灌一些数据进去,好歹要让数据撑破一个索引数据页,这样分支节点索引数据页就出来了,看下面的例子:

从图中可以看到,当我插入1000条数据的时候,已经出现了一个分支节点(120号索引数据页),三个叶子节点(121,126),叶子 节点的数据页内容我也说过了,现在我很好奇”分支节点“中保存着什么内容???我好兴奋,我要导出120号索引数据页了。。。


dbcc traceon(3604)
dbcc page(Ctrip,1,120,1)

简单分析下slot0:06000000 00ad0000 000100 的内容

00000000:叶子索引页中的最小key值(这里有点特殊,除一行记录不是保存最小值以外,其余都是的),转换为十进制就是0。

ad:叶子索引页的页号,转换为十进制就是173。

1:叶子索引页的文件号,转换为十进制就是1.

不过通过分析,我们看到了,其实分支节点中保存着有两个值,一个childpage的minkey,一个childpage的pageid,同理,其他的槽位也是这样。我们换个参数命令,让结果更直观点,记录中就是保存着”pageID“和”minKey“。

这样的话,我脑海中就有一张图出来了,不知道你现在是否有了????

通过上面的分析,除了第一行记录不是保存子索引页中最小key的值外,其他记录都是提取子索引页中的最小索引键值,这一点要注意。。。也许对sqlserver团队来说,只要判断小于449的话就直接去(1:173)数据页,小于889的直接去(1:121)数据页就可以啦。。。

当你看到这里的时候,不知道你是否已经明白,为什么表中只能有一个聚集索引呢???好了,希望对你有所帮助。

Sql Server之旅——第三站 解惑那些背了多年聚集索引的人相关推荐

  1. Sql Server之旅——第四站 你必须知道的非聚集索引扫描

    非聚集索引,这个是大家都非常熟悉的一个东西,有时候我们由于业务原因,sql写的非常复杂,需要join很多张表,然后就泪流满面了...这时候就有DBA或者资深的开发给你看这个猥琐的sql,通过执行计划一 ...

  2. Sql Server之旅——第十一站 简单说说sqlserver的执行计划

    原文:Sql Server之旅--第十一站 简单说说sqlserver的执行计划 我们知道sql在底层的执行给我们上层人员开了一个窗口,那就是执行计划,有了执行计划之后,我们就清楚了那些烂sql是怎么 ...

  3. Sql Server之旅——第五站 确实不得不说的DBCC命令

    Sql Server之旅--第五站 确实不得不说的DBCC命令 原文:Sql Server之旅--第五站 确实不得不说的DBCC命令 今天研发中心办年会,晚上就是各自部门聚餐了,我个人喜欢喝干红,在干 ...

  4. Sql Server之旅——第六站 为什么都说状态少的字段不能建索引

    我们在学sqlserver的时候,大多教科书和前辈们都说状态少的字段不要建索引,由此带来的开销还不如不建索引,但是这句话有多少人真的知道,或者说有多少人真的对此有比较深刻的理解,而不是听别人道听途说. ...

  5. Sql Server之旅——第八站 看公司这些DBA们设计的这些复合索引

    这一篇再说下索引的最后一个主题,索引覆盖,当然学习比较好的捷径是看看那些大师们设计的索引,看从中能提取些什么营养的东西,下面我们看看数据库中一个核心的Orders表. 一:查看表的架构 1. 先查看这 ...

  6. Sql Server之旅——第七站 复合索引和include索引到底有多大区别?

    索引和锁,这两个主题对我们开发工程师来说,非常的重要...只有理解了这两个主题,我们才能写出高质量的sql语句,在之前的博客中,我所说的索引都是单列索引...当然数据库不可能只认单列索引,还有我这篇的 ...

  7. Sql Server之旅——第十站 简单说说sqlserver的执行计划

    我们知道sql在底层的执行给我们上层人员开了一个窗口,那就是执行计划,有了执行计划之后,我们就清楚了那些烂sql是怎么执行的,这样 就可以方便的找到sql的缺陷和优化点. 一:执行计划生成过程 说到执 ...

  8. Sql Server之旅——第十三站 深入的探讨锁机制

    上一篇我只是做了一个堆表让大家初步的认识到锁的痉挛状态,但是在现实世界上并没有这么简单的事情,起码我的表不会没有索引对吧,还有就是我的表一定会有很多的连接过来,10:1的读写,很多码农可能都会遇到类似 ...

  9. Sql Server之旅——第十二站 sqltext的参数化处理

    Sql Server之旅--第十二站 sqltext的参数化处理 原文:Sql Server之旅--第十二站 sqltext的参数化处理 说到sql的参数化处理,我也是醉了,因为sql引擎真的是一个无 ...

最新文章

  1. 树的高度(小米2017秋招真题)
  2. Dajngo admin使用
  3. API性能优化之异步
  4. 高端企业级存储IBM XIV访谈视频
  5. Andoid TextView显示富文本html内容及问题处理
  6. CALLING PROCEDURES USING CALL AND RET
  7. mysql一张表可以用吗_MySQL表操作
  8. 拿来就能用!如何用 AI 算法提高安全运维效率? | 技术头条
  9. JavaScript 高级程序设计 笔记
  10. 没有币如何复制百度文库中的文章
  11. 常用测试工具-----XCAP
  12. Java实现Zip文件解压到指定目录
  13. centos7 vi保存退出_vi保存退出命令 - 卡饭网
  14. 隋政军---将木屋烧烤打造成中国领先的烧烤品牌
  15. untiy 监听屏幕点击 物体(实现)
  16. android apk可安装成功但无法运行提示dex文件异常
  17. 星女郎PK谋女郎 颜值衣品谁更胜一筹?
  18. 虚拟机Win 7中重新 划分 分区 合并 磁盘
  19. windows 下 用 dos 备份 oracle 数据库,并删除七天前的备份
  20. itext html转换pdf,itext转换html成pdf(支持中文、图片)

热门文章

  1. C#网络编程(订立协议和发送文件) - Part.4
  2. border:none 与border:0的区别
  3. 如何在ashx页面获取Session值(未将对象引用设置到对象的实例) (转)
  4. Win2003中apache2整合tomcat5和iis6
  5. (转)WCF教程系列(1)-创建第一个WCF程序
  6. ASP.NET 视频截图功能的C#代码
  7. assistant字体_如何使用Google Assistant设置和致电家庭联系人
  8. wi-fi共享大师免广告_如何保护Wi-Fi网络免受入侵
  9. Linux就该这么学---第七章(LVM逻辑卷管理器)
  10. Unity 游戏框架搭建 (九) 减少加班利器-QConsole