索引壓縮在實際生產中應用的探討

sundog315發表於2010-06-17
關於索引壓縮的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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章