前段时间有人提到说,表的业务量没怎么变化,怎么某个索引的索引表空间却增长得有点快?这是灵魂的拷问。通常我们会联想到是否索引字段的值变长导致的?那么本文将带大家了解另一种导致索引突增的场景。
了解oracle的朋友,多少都听过索引分裂这个名词。但是索引的90-10、50-50分裂,您可能不一定了解它的触发场景。下面我将通过实验例子,带大家了解一下,索引是怎么一步步长胖的。
实验环境:Oracle 19.6版本,RedHat 7.8 x86_64
实验简要说明:向一张空表插入8000条记录,分三批插入:第一批为1~3000、第二批为5001~8000、第三批为3001~5000。然后观察这三次数据插入后,索引分裂情况,索引占用空间及空间使用情况。
以下是实验步骤:
1)创建表test_210817,并在id列上创建一个普通索引

2)查看索引页分裂为0,索引初始化分配8个数据块,索引的对象ID为97137

3)插入第一批3千条记录,ID范围为1~3000,索引页有5次分裂,均为90-10分裂

4)收集表和索引统计信息,可以看到该索引分配了6个数据块

5)dump下索引树,可以看到所有索引页子节点(除8389160这个数据块之外),可用空间基本就剩几个字节了

6)接着,我们插入第二批3千条记录,ID范围为5001~8000,索引页有7次分裂,均为90-10分裂

7)收集表和索引统计信息,可以看到该索引分配了12个数据块

8)dump下索引树,可以看到所有索引页子节点(除8389197这个数据块之外),可用空间基本就剩几个字节了

9)最后,我们插入第三批2千条记录,ID范围为3001~5000,索引页有9次分裂,均为50-50分裂。到了这一步,您可能就有疑问了,为什么不是之前的90-10?原因是我们在插入第二批数据后,索引树中,索引值最大是8千,而第三批数据的值是介于3001~5000,所以采用50-50方式分裂,分裂完后,大概有1/2空间是空闲着,后续的记录都是单调递增,其实那部分空间就没法使用上

10)收集表和索引统计信息,可以看到该索引分配了20个数据块,我们可以算出,第三批这2千条记录,反而占用了8个数据块,而第二批3千条记录却只用了6个数据块

11)dump下索引树,可以看到所有索引页子节点(除8389217这个数据块之外),可用空间基本都是数据块的一半

12)最后,我们看一下索引的相关统计信息

至此,通过上面实验数据和数据库原理去说明了我们可能容易忽略的一些场景。对于怎样去回收这些空间,方法其实很多,以后有空再聊这块。




