索引壓縮在實際生產中應用的探討
關於索引壓縮的Internal請參見http://www.itpub.net/thread-1285279-1-1.html
主要是想探討一下索引壓縮在什麼情況下使用會更有意義?
採用的是如下的測試方法:
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則類似於一些狀態列。
壓縮後,大小的比較:
當disitnct value降至總數量的10%時,壓縮比率基本上就穩定在恆定的值上了,對於這個例子,壓縮比率為:64.7%
既然節省了空間,那麼,必然會消耗更多的CPU,我們來看看非壓縮與壓縮索引對於insert及update的影響(均採用執行3次取平均值,單位秒):
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的情況。不足之處請指正
主要是想探討一下索引壓縮在什麼情況下使用會更有意義?
採用的是如下的測試方法:
CODE:
conn test/testdrop 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 |
既然節省了空間,那麼,必然會消耗更多的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 |
綜上,如果選擇合適的話,我們可以透過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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Nuxt配合Node在實際生產中的應用UX
- 探討iOS 中圖片的解壓縮到渲染過程iOS
- 探討敏捷開發在軟體開發中的應用敏捷
- 六西格瑪管理在北京IT專案中的應用探討
- 【實驗】【索引壓縮】索引壓縮演示及優缺點總結索引
- TRIZ理論在洗碗機設計中應用探討
- Bootstrap在實際生產開發中的使用心得boot
- Linux在實際中的應用Linux
- Zip 壓縮、解壓技術在 HTML5 瀏覽器中的應用HTML瀏覽器
- 高效壓縮點陣圖在推薦系統中的應用
- 六西格瑪在農業領域的應用探討
- 策略模式在實際業務中的應用模式
- 策略模式在業務中的實際應用模式
- IT職場:如何將DOE(實驗設計)應用於實際生產過程中?
- 【數字孿生】數字孿生模型在產品構型管理中應用探討;不可忽視的輕量級三維視覺化技術...模型視覺化
- oracle 索引壓縮Oracle索引
- 深度強化學習在時序資料壓縮中的應用強化學習
- 索引在ORACLE中的應用分析索引Oracle
- 雲技術應用探討
- 高壓貼片電容在電源產品中的應用
- 關於MSSQL中計算列上建索引的探討SQL索引
- python建立elasticsearch索引的探討PythonElasticsearch索引
- Runtime在實際開發中的應用
- python 在實際生產過程中需要編譯嘛?Python編譯
- 探碼智慧智慧大資料視覺化在應用場景中的實際案例大資料視覺化
- 實用的壓縮解壓工具:WinZip for MacMac
- 並查集在實際問題中的應用並查集
- JNI解析以及在Android中的實際應用Android
- 深入探討ORA-04031的產生原因及解決方法
- 探討基於資訊系統的專案型生產管理
- 重新開貼!探討web應用中ResultSet返回的資料表示Web
- Sqlserver表和索引壓縮SQLServer索引
- MySQL壓縮表的一種應用MySql
- 唯品會 JIT模式 應用探討模式
- 無服務計算應用場景探討及 FaaS 應用實戰
- Google Guava 在實際場景中的應用封裝GoGuava封裝
- 策略模式解析以及在Android中的實際應用模式Android
- HTTP/2特性及其在實際應用中的表現HTTP