关于索引压缩的Internal请参见
http://www.itpub.net/thread-1285279-1-1.html主要是想探讨一下索引压缩在什么情况下使用会更有意义?
采用的是如下的测试方法:
CODE:
conn test/test
drop table t purge;
create table t (a varchar2(10));
create index t_idx on t(a);
set timing on
declare
i integer;
begin
execute immediate 'truncate table t';
for i in 0..500000 loop
insert into t select lpad(trunc(dbms_random.value*30000),8,'0') from dual;
end loop;
commit;
end;
/
declare
i integer;
row_id varchar2(20);
begin
for i in 0..100000 loop
select t.rowid into row_id from t sample(0.005) where rownum=1;
update t
set t.a =
(select lpad(trunc(dbms_random.value * 30000), 8, '0') from dual)
where rowid = row_id;
end loop;
commit;
end;
/
select blocks*8/1024 from user_segments where segment_name='T_IDX';
drop index t_idx;
create index t_idx on t(a) compress;
declare
i integer;
begin
execute immediate 'truncate table t';
for i in 0..500000 loop
insert into t select lpad(trunc(dbms_random.value*30000),8,'0') from dual;
end loop;
commit;
end;
/
declare
i integer;
row_id varchar2(20);
begin
for i in 0..100000 loop
select t.rowid into row_id from t sample(0.005) where rownum=1;
update t
set t.a =
(select lpad(trunc(dbms_random.value * 30000), 8, '0') from dual)
where rowid = row_id;
end loop;
commit;
end;
/
select blocks*8/1024 from user_segments where segment_name='T_IDX';改变dbms_random.value后的值来改变distinct value的数量,分别取值为:
500000/400000/300000/200000/100000/80000/50000/30000/5000/500
以模拟不同的实际情况,500000类似于主键而500则类似于一些状态列。
压缩后,大小的比较:
|
500000 |
400000 |
300000 |
200000 |
100000 |
80000 |
50000 |
30000 |
5000 |
500 |
| 压缩 |
17 |
17 |
17 |
17 |
17 |
17 |
17 |
17 |
17 |
17 |
| 非压缩 |
19 |
18 |
16 |
15 |
13 |
12 |
11 |
11 |
11 |
11 |
当disitnct value降至总数量的10%时,压缩比率基本上就稳定在恒定的值上了,对于这个例子,压缩比率为:64.7%
既然节省了空间,那么,必然会消耗更多的CPU,我们来看看非压缩与压缩索引对于insert及update的影响(均采用执行3次取平均值,单位秒):
|
非压缩 |
500000 |
400000 |
300000 |
200000 |
100000 |
80000 |
50000 |
30000 |
5000 |
500 |
| insert |
47.22 |
51.84 |
50.56 |
52.58 |
51.18 |
53.39 |
51.45 |
50.97 |
51.75
|
54.66 |
53.18 |
| update |
18.19 |
19.6 |
19.76
|
19.03 |
18.77 |
20.22 |
19.49 |
19.56 |
19.75 |
20.45 |
20.11 |
insert时间增加了:10.45%,update时间增加了:8.15%
综上,如果选择合适的话,我们可以通过10%左右的写性能损耗换取35.3%的读性能的提升及存储空间的降低
那么,到底什么情况下适合对索引进行压缩呢?
1.索引选择度不高,disitnct value/num_rows小于0.1
2.访问路径大部分为Index Full Scan 或 Index Fast Full Scan的索引
3.访问路径为Index Range Scan,但每次读的块数高,即avg_leaf_blocks_per_key高的索引
其中,1为必要条件。
以上,是对索引压缩的初步探讨,这里只考虑了单列索引及列类型为varchar2的情况。不足之处请指正
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/19423/viewspace-665549/
,如需转载,请注明出处,否则将追究法律责任。