ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 索引压缩在实际生产中应用的探讨

索引压缩在实际生产中应用的探讨

原创 Linux操作系统 作者:sundog315 时间:2010-06-17 16:14:09 0 删除 编辑
关于索引压缩的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博客 ” ,链接:http://blog.itpub.net/19423/viewspace-665549/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2010-01-05

  • 博文量
    126
  • 访问量
    503852