更新索引字段、插入一条数据、删除一条数据都会造成索引的维护从而造成性能的一定影响 。在不同情况下,性能影响是不同的 。比如当你有一个聚集索引,插入的数据又都是在末尾,这样几乎是不会造成数据移动,影响较小;如果插入的数据在中间位置,一般会导致数据移动,而且可能产生分页和页碎片,影响就会稍大一点(如果插入到的中间页有足够的剩余空间容纳插入的数据,而且位置是在页末,也是不会造成数据移动)
03索引的结构
很多人认为SqlServer的索引是B树结构,那它到底长什么个模样呢,可以用Sql语句来查看它的逻辑呈现 。
新建查询执行语法: DBCC IND(Test,OrderBo,-1) –其中Test库的OrderBo表有1万条数据,有聚集索引Id主键字段 。
执行结果:
如上图,看到一个IndexLevel=2的索引页2112(这边它就是B树的根节点,IndexLevel最大的就是根节点,往下就是子级、子子级…只有一个根页作为B树结构的访问入口点),说明一定还有IndexLevel=1的索引页和IndexLevel=0的叶子页 。由于这边是聚集索引,因此当IndexLevel=0的叶子页就是数据页,存储的是一笔一笔的物理数据 。如上图也可以看到,IndexLevel=0的行的PageType等于1,就是代表数据页;而如果是非聚集索引,IndexLevel=0的叶子页,PageType是等于 2,仍然是索引页 。
同样,用Sql命令DBCC PAGE看一看
【难检字笔画索引是什么意思 索引是什么意思】— DBCC TRACEON(3604,-1)
DBCC PAGE(Test,1,2112,3)
–根节点2112,可以查出它的两个子节点2280和2448,然后对这两个子节点再作DBCC PAGE查询
DBCC PAGE(Test,1,2280,3)
DBCC PAGE(Test,1,2448,3)
如上图,IndexLevel=2的2112页有两个IndexLevel=1的子节点2280和2448,子节点下又有子节点,每个节点负责不同的索引键值的区间(即上图的“Id(key)”栏位,第一行值是Null,表示最小值或倒序时的最大值) 。这样的层级关系是不是就是一棵B树结构,其中IndexLevel其实就是B树结构中的高度Height 。
SqlServer在索引中查找某一笔记录时,是从根节点往下找到叶子节点,因为所有数据地址都有存在叶子节点,这其实是B+树的特点之一(B树特点是如果查找的值在非叶子节点就找到,则就能直接返回,显然SqlServer不是这么做) 。
既然一定会找到叶子节点,那么索引包含列只要在叶子节点记录就可以了,即非叶子节点没有记录包含列,“索引包含列”见下文第3章节 。
B+树这个特点(所有数据地址都有存在叶子节点)也利于between value1 and value2 区间查询,只要找到value1和value2(在叶子节点),然后把中间串起来就是要的结果了 。
SqlServer索引结构更像是B+树,最终是B树和B+树的混合版,数据结构都是人定的,不一定就是纯粹的B树或者单纯的B+树 。
问题来了,Oracle、mysql、sqlserver在索引设计上有什么区别呢?哪种方式更优,大家有什么好的想法可以在下方留言一起探讨,后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注一下~
(今完)
推荐阅读
- 世界上最难征服的石头之一 有勇气征服吗
- 辐射避难所新手布局
- 人工增雪的方法
- 原神良药难求隐藏成就攻略 原神医用笔迹成就完成攻略
- 生态灾难有哪些举例子
- 绿云兰花怎么养
- 汉字笔画最多的字172画 汉字笔画最多的字
- 2020年5G能全覆盖吗
- 喝醉酒之后是否很难受 解酒食疗药膳和解酒粥来帮你
- 核桃是不是高蛋白食物,核桃吃多了胃难受怎么办