对于update操作,索引将对原先的数据进行删除标记,然后增加一条新的记录,因此很多人,包括我在内,就有一个错误观念:大批量的update更新操作,就可能造成索引存储空间浪费,我们需要定期对索引进行重建。实际上,当leaf block被标记为删除记录的时候,这些空间能被ORACLE自动清除和重用。
以下是Richard Foote实验步骤:
1、创建表和索引
SQL>create table test_update (id number,name varchar2(10));
SQL>create index test_update_idx on test_update(name);
SQL>insert into test_update values(1, 'BOWIE');
SQL>commit;
2、dump 索引数据块
SQL>select header_file, header_block
from dba_segments
where segment_name='TEST_UPDATE_IDX'
HEADER_FILE HEADER_BLOCK
-------------------------- ---------------------------
6 3355
SQL>alter session set tracefile_identifier=yzb;
SQL>alter system dump datafile 6 block 3356;
查看trace文件:
..........
kdxconro 1 (该数据块索引有1行)
..........
kdxlende 0 (该数据块索引被删除的是0行)
row#0[8017] flag: ------, lock: 2, len=15
col 0; len 5; (5): 42 4f 57 49 45
col 1; len 6; (6): 01 80 0d 17 00 00
3、update表的数据,并dump索引数据块信息
SQL>update test_update set name='ZIGG' where id=1;
SQL>commit;
SQL>alter system dump datafile 6 block 3356;
查看trace文件:
..........
kdxconro 2 (该数据块索引有2行)
..........
kdxlende 1 (该数据块索引被删除的是1行)
row#0[8017] flag: ---D--, lock: 2, len=15 (标识为删除)
col 0; len 5; (5): 42 4f 57 49 45
col 1; len 6; (6): 01 80 0d 17 00 00
row#1[8003] flag: ------, lock: 2, len=14
col 0; len 4; (4): 5a 49 47 47
col 1; len 6; (6): 01 80 0d 17 00 00
SQL>index test_update_idx validate structure;
SQL>select del_lf_rows from index_stats;
DEL_LF_ROWS
------------------
1
4、插入一个新的数据
SQL>insert into test_update value (2, 'PINK FLOYD');
SQL>commit;
SQL>alter system dump datafile 6 block 3356;
查看trace文件:
..........
kdxconro 2 (该数据块索引有1行)
..........
kdxlende 0 (该数据块索引被删除的是0行)
row#0[7983] flag: ------, lock: 2, len=20
col 0; len 10; (10): 50 49 4e 4b 20 46 4c 4f 59 44
col 1; len 6; (6): 01 80 0d 17 00 01
row#1[8003] flag: ------, lock: 0, len=14
col 0; len 4; (4): 5a 49 47 47
col 1; len 6; (6): 01 80 0d 17 00 00
原先标记为删除的行消失了。
SQL>analyze index test_update_idx validate structure;
SQL>select del_lf_rows from index_stats;
DEL_LF_ROWS
------------------
0
以下是Richard Foote实验步骤:
1、创建表和索引
SQL>create table test_update (id number,name varchar2(10));
SQL>create index test_update_idx on test_update(name);
SQL>insert into test_update values(1, 'BOWIE');
SQL>commit;
2、dump 索引数据块
SQL>select header_file, header_block
from dba_segments
where segment_name='TEST_UPDATE_IDX'
HEADER_FILE HEADER_BLOCK
-------------------------- ---------------------------
6 3355
SQL>alter session set tracefile_identifier=yzb;
SQL>alter system dump datafile 6 block 3356;
查看trace文件:
..........
kdxconro 1 (该数据块索引有1行)
..........
kdxlende 0 (该数据块索引被删除的是0行)
row#0[8017] flag: ------, lock: 2, len=15
col 0; len 5; (5): 42 4f 57 49 45
col 1; len 6; (6): 01 80 0d 17 00 00
3、update表的数据,并dump索引数据块信息
SQL>update test_update set name='ZIGG' where id=1;
SQL>commit;
SQL>alter system dump datafile 6 block 3356;
查看trace文件:
..........
kdxconro 2 (该数据块索引有2行)
..........
kdxlende 1 (该数据块索引被删除的是1行)
row#0[8017] flag: ---D--, lock: 2, len=15 (标识为删除)
col 0; len 5; (5): 42 4f 57 49 45
col 1; len 6; (6): 01 80 0d 17 00 00
row#1[8003] flag: ------, lock: 2, len=14
col 0; len 4; (4): 5a 49 47 47
col 1; len 6; (6): 01 80 0d 17 00 00
SQL>index test_update_idx validate structure;
SQL>select del_lf_rows from index_stats;
DEL_LF_ROWS
------------------
1
4、插入一个新的数据
SQL>insert into test_update value (2, 'PINK FLOYD');
SQL>commit;
SQL>alter system dump datafile 6 block 3356;
查看trace文件:
..........
kdxconro 2 (该数据块索引有1行)
..........
kdxlende 0 (该数据块索引被删除的是0行)
row#0[7983] flag: ------, lock: 2, len=20
col 0; len 10; (10): 50 49 4e 4b 20 46 4c 4f 59 44
col 1; len 6; (6): 01 80 0d 17 00 01
row#1[8003] flag: ------, lock: 0, len=14
col 0; len 4; (4): 5a 49 47 47
col 1; len 6; (6): 01 80 0d 17 00 00
原先标记为删除的行消失了。
SQL>analyze index test_update_idx validate structure;
SQL>select del_lf_rows from index_stats;
DEL_LF_ROWS
------------------
0
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/354732/viewspace-605530/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/354732/viewspace-605530/