一、索引分裂

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树索引分裂的更多相关文章

  1. 浅谈B+树索引的分裂优化(转)

    http://www.tamabc.com/article/85038.html 从MySQL Bug#67718浅谈B+树索引的分裂优化   原文链接:http://hedengcheng.com/ ...

  2. 从MySQL Bug#67718浅谈B+树索引的分裂优化(转)

    原文链接:http://hedengcheng.com/?p=525 问题背景 今天,看到Twitter的DBA团队发布了其最新的MySQL分支:Changes in Twitter MySQL 5. ...

  3. MySQL Bug#67718 浅谈B+树索引的分裂优化

    原文链接:http://hedengcheng.com/?p=525 问题背景 今天,看到Twitter的DBA团队发布了其最新的MySQL分支:Changes in Twitter MySQL 5. ...

  4. InnoDB 中 B+ 树索引的分裂

    数据库中B+树索引的分裂并不总是从页的中间记录开始,这样可能会导致空间的浪费,例如下面的记录: 1, 2, 3, 4, 5, 6, 7, 8, 9 插入式根据自增顺序进行的,若这时插入10这条记录后需 ...

  5. MySQL的B树索引与索引优化

    MySQL的MyISAM.InnoDB引擎默认均使用B+树索引(查询时都显示为"BTREE"),本文讨论两个问题: 为什么MySQL等主流数据库选择B+树的索引结构? 如何基于索引 ...

  6. MySQL之B+树索引(转自掘金小册 MySQL是怎样运行的,版权归作者所有!)

    每个索引都对应一棵B+树,B+树分为好多层,最下边一层是叶子节点,其余的是内节点.所有用户记录都存储在B+树的叶子节点,所有目录项记录都存储在内节点. InnoDB存储引擎会自动为主键(如果没有它会自 ...

  7. B树索引与索引优化

    B树索引与索引优化 MySQL的MyISAM.InnoDB引擎默认均使用B+树索引(查询时都显示为“BTREE”),本文讨论两个问题: 为什么MySQL等主流数据库选择B+树的索引结构? 如何基于索引 ...

  8. 谈谈InnoDB中的B+树索引

    索引类似于书的目录,他是帮助我们从大量数据中快速定位某一条或者某个范围数据的一种数据结构.有序数组,搜索树都可以被用作索引.MySQL中有三大索引,分别是B+树索引.Hash索引.全文索引.B+树索引 ...

  9. CMU数据库(15-445)实验2-b+树索引实现(上)

    Lab2 在做实验2之前请确保实验1结果的正确性.不然你的实验2将无法正常进行 环境搭建地址如下 https://www.cnblogs.com/JayL-zxl/p/14307260.html 实验 ...

随机推荐

  1. Hibernate入门(十)inverse

    双向关联产生多余的SQL语句 /** * 添加一个订单到id为6的客户中 */ @Test public void fun1(){ Session session = HibernateUtils.g ...

  2. Hibernate入门(五)---------事务管理

    在Hibernate中,可以通过代码来操作管理事务,如通过“Transaction tx = session.beginTransaction()”,开启一个事务,持久化操作后,通过"tx. ...

  3. Https协议报错:com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl解决方法

    旭日Follow_24 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/xuri24/article/details/82220333 所用应用服务器:JBoss服务 ...

  4. could not read Username for 'https://github.com': No error

    用idea往github上push代码的时候,突然的不能用了. 报could not read Username for 'https://github.com': No error错误. 原因不明. ...

  5. laravel接值 get post

    laravel使用一种简单的方式来访问用户提交的信息. 你可以用统一的方式来访问用户提交的信息,而不用为用户提交信息的方式操心. 引用类:use Illuminate\Support\Facades\ ...

  6. 3;XHTML排列清单控制标记

    1.无序号条例式清单<ul> 2.有序号条例式清单<ol> 3.无序列表和有序列表的结合应用 4.叙述式清单<dl> 排列清单控制标记可以创建一般的列表.编号列表或 ...

  7. 08-HTML-框架标签

    <html> <head>  <title>框架标签学习</title>  <meta charset="utf-8"/> ...

  8. js 毫秒转天时分秒

    formatDuring: function(mss) { var days = parseInt(mss / (1000 * 60 * 60 * 24)); var hours = parseInt ...

  9. Html5新增标签的学习。

    随笔,记录的比较随便. 今天新学习了9个标签. <audio> 简单的说就是一个音频标签,他的主要常用属性有src=""音频的路径 controls="con ...

  10. MaltReport2:通用文档生成引擎

    UPDATED: 本文仅适用 MaltReport 2.x ,3.x 版本文档还在撰写当中,目前请参考项目中的 Samples. MaltReport 是我几年前写的开源单据.报表引擎,最近进行了较大 ...