索引壓縮在實際生產中應用的探討
關於索引壓縮的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
- 深入探討Function Calling:在Semantic Kernel中的應用實踐Function
- 探討iOS 中圖片的解壓縮到渲染過程iOS
- 人工智慧在資料壓縮中的應用人工智慧
- 探討敏捷開發在軟體開發中的應用敏捷
- TRIZ理論在洗碗機設計中應用探討
- Linux在實際中的應用Linux
- 六西格瑪管理在北京IT專案中的應用探討
- python建立elasticsearch索引的探討PythonElasticsearch索引
- 從實際案例中探討io中的延遲效能的作用
- 高效壓縮點陣圖在推薦系統中的應用
- 六西格瑪在農業領域的應用探討
- 深度強化學習在時序資料壓縮中的應用強化學習
- 【數字孿生】數字孿生模型在產品構型管理中應用探討;不可忽視的輕量級三維視覺化技術...模型視覺化
- 探碼智慧智慧大資料視覺化在應用場景中的實際案例大資料視覺化
- 策略模式在實際業務中的應用模式
- 策略模式在業務中的實際應用模式
- 實用的壓縮解壓工具:WinZip for MacMac
- python 在實際生產過程中需要編譯嘛?Python編譯
- 策略模式解析以及在Android中的實際應用模式Android
- 並查集在實際問題中的應用並查集
- 在實際應用中聯合體union的妙用
- IT職場:如何將DOE(實驗設計)應用於實際生產過程中?
- Sqlserver表和索引壓縮SQLServer索引
- 唯品會 JIT模式 應用探討模式
- 無服務計算應用場景探討及 FaaS 應用實戰
- Google Guava 在實際場景中的應用封裝GoGuava封裝
- 5G在工業中應用的討論
- 怎麼把影片壓縮?實用又簡單的壓縮影片方法
- 用程式碼探討KVC/KVO的實現原理
- 用程式碼探討 KVC/KVO 的實現原理
- sklearn中的pipeline實際應用
- OB有問必答 | OceanBase的記憶體管理是怎麼做的?在實際的生產環境中是如何應用的?記憶體
- Linux中檔案的壓縮和解壓縮Linux
- [Elasticsearch] ES 的Mapping 設計在實際場景中應用ElasticsearchAPP
- ASP.NET Core中的響應壓縮ASP.NET
- 探一探快應用的虛實
- Python實現壓縮和解壓縮Python
- B樹在資料庫索引中的應用剖析資料庫索引