B树索引分裂
一、索引分裂
1. 什么是分裂
在开始介绍之前,我们先来搞清楚什么是索引分裂吧。“索引分裂”就是索引块的分裂,当一次DML事务操作修改了索引块上的数据,但是旧有的索引块没有足够的空间来容纳新修改的数据,那么将分裂出一个新索引块,旧有块的部分数据放到新开辟的索引块上去,这个过程就称为索引块的分裂(INDEX BLOCK SPLIT)。
如图1所示,当有新值插入到L4叶节点块的时候,此时L4叶节点块是“充满”状态,已经没有足够的空间来存储新值了,此时会在B2分支节点下,分裂出一个新的叶节点L5来存储新值。如果分支节点B2也是“充满”了呢?那就要进行分支节点的分裂,即在ROOT根节点下,分裂出一个新的分支节点出来。依此类推,如果根节点也“充满”了,则需要进行根节点的分裂。如果发生了根节点的分裂,也意味着B树的高度(BTREE LEVEL)增加了一个层次。对真正意义上的树来说,这种生长是好事,但对B树索引来说,这就不是什么好事情了,B树索引的高度需要严格控制的。
图1 新值产生索引分裂
2. 分裂的类型
从上面的介绍来说,我们大致可以将索引分裂归为三种类型:根节点分裂、分支节点分裂、叶节点分裂。当然,也可以说是两种类型,因为根节点分裂实质上一种特殊的分支节点分裂。我们首要需要关注的是其中叶节点的分裂,因为它是最频繁发生,对性能影响最直接的因素。
我们说过分裂出新节点后,会将一部分旧有的数据放到新节点上去,按照数据迁移量的比例,我们又可以将索引分裂分为两种类型:9-1分裂和5-5分裂。如果叶节点和分支节点同时发生分裂,其分裂比例的类型是相同的,即要么都是9-1分裂,要么都是5-5分裂。
q 9-1分裂:绝大部分数据还保留在旧有节点上,仅有非常少的一部分数据迁移到新节点上。
q 5-5分裂:旧节点和新节点上的数据比例几乎是持平的。
我们通常所说的索引分裂,大部分情况都指的是9-1的分裂。当事务向索引的最右侧的叶节点上插入一条大于或等于现有索引块上最大值的数据,且该索引块上不存在其他未提交的事务,如果没有足够的空间,就会发生9-1分裂。
很遗憾的是,当发生左侧节点上插入数据的时候,发生9-1分裂就会出现一些问题。如图2所示,当向左侧分支节点插入新值,即使其兄弟右侧分支节点数据区中没有数据(或者说没有右节点),它们的父节点都会发生分裂,极端情况下甚至会促使B树的高度增长,这对索引性能来说是很悲剧的,这一缺陷在10g以前的版本中都是存在的。
图2 左节点9-1分裂
从Oracle 10g开始,对于左侧节点的数据插入行为,引进了5-5分裂的方式,修正了9-1分裂造成的缺陷。如图3所示,当左侧分支节点B1已经“充满”状态,会去判断其兄弟右侧分支节点B2是否有空间,如果有,则将部分数据(5:5的比例)迁移到右侧分支节点上,这样就避免了分支节点甚至根节点的分裂。
图3 左节点5-5分裂
5-5分裂的方式也不是万能的,如果过于频繁的5-5分裂也会造成索引空间使用率不高,使得索引结构看上去像一个“虚胖子”,不够“结实’,同样会造成性能问题。
那什么时候会发生5-5分裂呢?简单地来说就是在索引需要分裂,但不能进行9-1分裂的时候就会触发5-5分裂。这听起来像一句废话,可将9-1分裂的条件反过来看,也正是5-5分裂发生的条件:
q 左侧节点发生新值插入时(新值小于索引中的最大值);
q 发生DML操作,索引块上没有足够空间分配新的ITL槽;
q 新值待插入的索引块上存在其他未提交的事务。
对比一下9-1分裂和5-5分裂的发生场景。9-1分裂通常是索引的键值是递增的,表上的事务并发量比较低,可保证新的数据块上有较大的空闲空间插入新值。5-5分裂通常是表上的事务并发度较高,操作的数据是无序的,需保证分裂的新旧数据块上有相对较大的空闲空间以容纳新事务的操作。
总体来看,不论是9-1分裂还是5-5分裂,对于性能来说,都不是什么好事。索引块的分裂意味着索引数据一定范围上的重组,其维护代价都是非常高昂的,应该尽可能地避免不必要的分裂发生。
B树索引分裂的更多相关文章
- 浅谈B+树索引的分裂优化(转)
http://www.tamabc.com/article/85038.html 从MySQL Bug#67718浅谈B+树索引的分裂优化 原文链接:http://hedengcheng.com/ ...
- 从MySQL Bug#67718浅谈B+树索引的分裂优化(转)
原文链接:http://hedengcheng.com/?p=525 问题背景 今天,看到Twitter的DBA团队发布了其最新的MySQL分支:Changes in Twitter MySQL 5. ...
- MySQL Bug#67718 浅谈B+树索引的分裂优化
原文链接:http://hedengcheng.com/?p=525 问题背景 今天,看到Twitter的DBA团队发布了其最新的MySQL分支:Changes in Twitter MySQL 5. ...
- InnoDB 中 B+ 树索引的分裂
数据库中B+树索引的分裂并不总是从页的中间记录开始,这样可能会导致空间的浪费,例如下面的记录: 1, 2, 3, 4, 5, 6, 7, 8, 9 插入式根据自增顺序进行的,若这时插入10这条记录后需 ...
- MySQL的B树索引与索引优化
MySQL的MyISAM.InnoDB引擎默认均使用B+树索引(查询时都显示为"BTREE"),本文讨论两个问题: 为什么MySQL等主流数据库选择B+树的索引结构? 如何基于索引 ...
- MySQL之B+树索引(转自掘金小册 MySQL是怎样运行的,版权归作者所有!)
每个索引都对应一棵B+树,B+树分为好多层,最下边一层是叶子节点,其余的是内节点.所有用户记录都存储在B+树的叶子节点,所有目录项记录都存储在内节点. InnoDB存储引擎会自动为主键(如果没有它会自 ...
- B树索引与索引优化
B树索引与索引优化 MySQL的MyISAM.InnoDB引擎默认均使用B+树索引(查询时都显示为“BTREE”),本文讨论两个问题: 为什么MySQL等主流数据库选择B+树的索引结构? 如何基于索引 ...
- 谈谈InnoDB中的B+树索引
索引类似于书的目录,他是帮助我们从大量数据中快速定位某一条或者某个范围数据的一种数据结构.有序数组,搜索树都可以被用作索引.MySQL中有三大索引,分别是B+树索引.Hash索引.全文索引.B+树索引 ...
- CMU数据库(15-445)实验2-b+树索引实现(上)
Lab2 在做实验2之前请确保实验1结果的正确性.不然你的实验2将无法正常进行 环境搭建地址如下 https://www.cnblogs.com/JayL-zxl/p/14307260.html 实验 ...
随机推荐
- JavaScript 笔记(二) 正则表达式
正则表达式 Regular Expression (regex regexp re) str.search(正则表达式) 检索str字符串 返回子串起始位置 str.replace(正则表达式,'要替 ...
- mysql zip安装
管理员运行cmd,进入bin目录1.在my.ini(mysql解压目录下)文件中复制下面内容 [client] port = 3306 [mysql] default-character-set=ut ...
- C# 程序运行进度显示Lable
public void test() { Thread.Sleep(); string vvv = ""; ; i < ;i++ ) { vvv = vvv +i.ToStr ...
- 你用过CSS3的这个currentColor新属性吗?使用与兼容性
currentColor顾名思意就是“当前颜色”,准确讲应该是“当前的文字颜色”,例如: .xxx { border: 1px solid currentColor; } currentColor表示 ...
- iOS---------- MBProgressHUD (1.0.0)的变动
1.改变菊花的颜色 // hud.color = [UIColor blackColor];--------------> hud.bezelView.color =[UIColor b ...
- Implemented the “Importance Sampling of Reflections from Hair Fibers”
Just the indirect specular pass by importance sampling. With all layers. Manually traced by 3D Ham ...
- ORACLE等待事件:SQL*Net message from client & SQL*Net message to client
在ORACLE当中有两个很常见的等待事件"SQL*Net message from client"与"SQL*Net message to client",两者 ...
- SQL Script
查某字段是否有汉字 SELECT*FROM TB WHERE COL LIKEN'%[吖-咗]%'
- MySQL8.0关于caching_sha2_password Plugin的一个Bug
今天在调试使用ansible进行标准化安装MySQL8.0时,发现关于caching_sha2_password plugin的一个bug. 在搭建主从复制时,按照手册说明需要创建用户: create ...
- C#编辑EXE使用的appSettings节点的Config文件
/// <summary> /// 保存配置文件的设定 /// </summary> /// <param name="Key"></pa ...