Oracle索引合并coalesce操作

索引rebuild和rebuild online是运维环境中经常遇到的问题。但是无论哪种,大数据索引对象的rebuild都是消耗资源的大规模操作,都需要进行时间窗规划,避免对在线系统运行有影响。

本篇主要介绍对索引的另一种精简操作方法:coalesce合并。从之前的讨论我们已经知道,索引结构一般是一个不断“退化”的平衡结构,如果有一个新值加入,就可能会伴随叶子节点拓展,甚至包括分支节点创建。而一个值被删除修改,叶子节点只是被标注为已删除,不会进行节点合并和回收。这样,正常环境下的索引应该是叶子“支离破碎”、“缓慢膨胀”的段结构。

回收空间、让叶子节点更加紧密是管理员考虑rebuild的基本出发动机。紧密的新索引的确空间占用比较小,检索速度也较快。但是之后插入、更新、删除的过程后,依然伴随着空间分配过程的损耗。所以,笔者个人认为:也许健康的索引结构就应该是“支离破碎”、“缓慢膨胀”。Coalesce操作提供的一种逻辑重组索引的方式,仅对索引树进行重组,不进行数据回收。

1、环境介绍

笔者选择11gR2进行实验。

SQL> select * from v$version;

BANNER

--------------------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

PL/SQL Release 11.2.0.3.0 - Production

CORE  11.2.0.3.0    Production

TNS for Linux: Version 11.2.0.3.0 - Production

NLSRTL Version 11.2.0.3.0 - Production

创建数据表T,构建索引。

SQL> create table t as select * from dba_objects ;

Table created

SQL> create index idx_t_id on t(object_id);

Index created

为了模拟效果,删除大部分数据构成死节点。

SQL> select max(object_id) from t;

MAX(OBJECT_ID)

--------------

164092 

SQL> delete t where object_id<164092;

77405 rows deleted 

SQL> commit;

Commit complete

重新收集统计量。

SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);

PL/SQL procedure successfully completed 

SQL> commit;

Commit complete 

SQL> select count(*) from t;

COUNT(*)

----------

1

2、coalesce操作

Delete操作既不会回收数据段,也不会回收索引段。当前一行数据表T对应的段信息如下:

SQL> select EXTENT_ID, FILE_ID, BLOCK_ID, BYTES, BLOCKS from dba_extents where owner='SYS' and segment_name='T';

EXTENT_ID    FILE_ID  BLOCK_ID      BYTES    BLOCKS

---------- ---------- ---------- ---------- ----------

0          1      86984      65536          8

1          1      86992      65536          8

2          1      87000      65536          8

3          1      87008      65536          8

4          1      87016      65536          8

5          1      87024      65536          8

6          1      87032      65536          8

7          1      88960      65536          8

8          1      88968      65536          8

9          1      88976      65536          8

10          1      88984      65536          8

11          1      88992      65536          8

12          1      89000      65536          8

13          1      89008      65536          8

14          1      90360      65536          8

15          1      91008      65536          8

16          1      89088    1048576        128

17          1      89216    1048576        128

18          1      89344    1048576        128

19          1      89472    1048576        128

EXTENT_ID    FILE_ID  BLOCK_ID      BYTES    BLOCKS

---------- ---------- ---------- ---------- ----------

20          1      89600    1048576        128

21          1      89728    1048576        128

22          1      89856    1048576        128

23          1      89984    1048576        128

24 rows selected

索引段如下:

SQL> select EXTENT_ID, FILE_ID, BLOCK_ID, BYTES, BLOCKS from dba_extents where owner='SYS' and segment_name='IDX_T_ID'; 

EXTENT_ID    FILE_ID  BLOCK_ID      BYTES    BLOCKS

---------- ---------- ---------- ---------- ----------

0          1      91704      65536          8

1          1      91712      65536          8

2          1      91720      65536          8

3          1      91728      65536          8

4          1      91736      65536          8

5          1      91744      65536          8

6          1      91752      65536          8

7          1      91760      65536          8

8          1      91768      65536          8

9          1      92544      65536          8

10          1      92552      65536          8

11          1      92560      65536          8

12          1      92568      65536          8

13          1      92576      65536          8

14          1      92584      65536          8

15          1      92592      65536          8

16          1      91776    1048576        128

17 rows selected

多extent结构,表示结构没有回收。下面使用analyze语句分析一下索引的情况:

SQL> analyze index idx_t_id validate structure;

Index analyzed

SQL> select height, blocks, lf_rows, lf_blks, lf_rows_len, lf_blk_len, br_rows, br_blks, del_lf_rows from index_stats;

HEIGHT    BLOCKS    LF_ROWS    LF_BLKS LF_ROWS_LEN LF_BLK_LEN    BR_ROWS    BR_BLKS DEL_LF_ROWS

---------- ---------- ---------- ---------- ----------- ---------- ---------- ---------- -----------

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1e58f333886cc328505d48533eefb5aa.html