閱讀603 返回首頁    go 阿裏雲 go 技術社區[雲棲]


平均提速20倍!Oracle 12c In-Memory最佳實踐

一、IM特性簡介

 

Oracle 12.1.0.2 引入了In-Memory Column Store(以下簡稱IM)新特性,該特性開啟後會在數據庫啟動階段在SGA中分配一塊靜態的內存池In-Memory Area,用於存放以列式存儲的用戶表。

 

列式存儲的優點是在訪問數據時隻需要訪問數據的部分列,而不像行式存儲,需要訪問數據的所有列。列式存儲可以避免大量不必要I/O,且每一列的列值即為索引,可以顯著提高查詢性能。

 

IM列式存儲並不會替換傳統的buffer cache行式存儲,而是作為補充,Oracle優化器會根據兩種方式的特點自行選擇適合的方式來取數據。

 

下圖展示Oracle以兩種方式存儲數據:

 

20161208100706581.jpg

 

IM可以對存入的表進行壓縮,壓縮級由低到高分別為:

 

  1. NO MEMCOMPRESS  

  2. MEMCOMPRESS FOR DML

  3. MEMCOMPRESS FOR QUERY LOW 

  4. MEMCOMPRESS FOR QUERY HIGH

  5. MEMCOMPRESS FOR CAPACIT LOW

  6. MEMCOMPRESS FOR CAPACITY HIGH

 

默認級別為MEMCOMPRESS FOR QUERY LOW,該級別在有效壓縮表的同時提供最佳的查詢性能,數據庫不對數據進行解壓讀取,而是采用數據字典壓縮方式,即刪除重複數據來減少內存使用。此外,其它更高的級別的壓縮方式需要對數據進行壓縮,會增加額外消耗。

 

二、IM特性測試

 

1.開啟IM特性

 

IM特性由inmemory_size 參數控製,隻要參數值大於0,該特性即被開啟,注意,inmemory_size 至少設置100M,否則無法啟動實例,報錯ORA-64353:

 

20161208100726347.png

 

以設置inmemory_size=10g 為例:

Alter system set inmemory_size=10g sid=‘db12c1’ scope=spfile;

 

重啟實例後,SGA分配時會多出一項IN-Memory Area,說明IM特性已被打開。

 

20161208100749945.jpg

 

2.IM性能測試

 

>>>> 

全表掃描

 

以一張36萬行的表進行全表掃描為例:

 

未開啟IM:

 

20161208100829256.jpg

 

開啟IM後:

 

20161208100902602.jpg

 

可以看到,開啟IM後TABLE ACCESS FULL變為TABLE ACCESS INMEMORY FULL,邏輯讀從6130降為6,CPU cost由427降為17,性能有成百上千倍的提升。

 

>>>> 

表連接查詢

 

im_tab_ja表有10萬條記錄,im_tab_jb表有2000多條記錄,兩表做關聯查詢測試。

 

未開啟IM特性:

 

20161208100923996.jpg

 

開啟IM特性:

 

20161208100943681.jpg

 

可以看到,IM對表關聯查詢的提升也非常明顯。

 

>>>> 

行式存儲更優的情況

 

im_tab_ja有10萬條數據,在im_tab_ja表的table_name列加索引,數據離散度很高,對應的索引選擇性也就較好,此時進行全字段查詢,過濾字段為table_name。

 

IM 特性開啟後默認情況下執行計劃並沒有走IM的掃描:

 

20161208101058959.jpg

 

指定執行計劃走IM:

 

20161208101121426.jpg

 

雖然強製執行計劃走了IM,但是邏輯讀是59,遠高於默認的走索引+行式存儲的執行計劃,可見在數據離散度較高,且通過索引條件過濾的掃描場景中,IM特性對性能並沒有提升,傳統的索引+行式存儲的執行計劃已經足夠,在默認情況下還是會根據查詢索引返回rowid的方式查找數據。

 

3.IM壓縮比測試

 

>>>> 

重複值對壓縮比的影響

 

由於IM壓縮是基於重複數據刪除的壓縮, 對300000條數據但不同數據隻有兩條的im_gender表和同樣有300000條數據但每條數據都不重複的im_table表進行壓縮測試。

 

20161208101138754.jpg

 

im_gender 表壓縮比達3.56,而im_phone的壓縮比隻有0.98,反而增大了。由此可知,重複值高有助於提高壓縮比,而幾乎無重複值的表壓縮效果就很差。

 

>>>> 

壓縮模式不同對壓縮比的影響

 

為了方便操作和對比,這裏調用了DBMS_COMPRESSION.GET_COMPRESSION_RATIO對壓縮比進行預估:

 

20161208101153380.jpg

 

可見,壓縮比隨著壓縮等級的提升而提升,這裏選擇被壓縮的表是根據dba_objects create as出來的,數據分布有一定的代表性,但在實際操作中,壓縮效果要根據具體情況具體分析。

 

三、IM生產實踐

 

目前,浙江移動X係統已經啟用了IM特性,在啟用特性之前,業務反饋查詢緩慢,業務頁麵將超時設置由30s調整至60s的情況下,仍然頻繁出現頁麵超時問題,業務高峰期的超時概率高達60%。經過深度分析發現業務SQL本身並無有效的過濾條件,最終隻能定位到分區全掃查詢,也就是無法單純從優化SQL的方式上進行解決。同時數據庫資源池上本身存在較多的pdb,大量的全表掃描消耗較多的IO資源,對其他的pdb也造成影響。

 

由於SQL承載的是分析類業務,通過分析該類表的統計信息發現數據離散度較低,比較符合IM的適用場景。在進行為期3周的嚴格測試和運維場景模擬實驗後,最終通過變更完成Oracle12C的IM特性在生產中的首次應用。

 

優化效果:查詢效率由幾十秒至數分鍾不等的查詢時間,降低至200ms完成目標數據的掃描。目前使用1個月以上,應用反饋頁麵響應速度良好,頁麵最終的響應速度在3s左右,平均提速20倍以上,業務成功率高達100%。

 

相關SQL的執行計劃前後對比:

 

啟用IM前:

 

20161208101212969.jpg

 

啟用IM後:

 

20161208101302809.jpg

 

物理讀由168357多降為0,邏輯由168493降為24,cpu cost由29840降為2741,執行時間由6.65s降為0.23s, 效果顯著。

 

壓縮比情況:

 

20161208101315628.jpg

 

壓縮比在默認壓縮級別下已經達到了5-12倍的壓縮比例。

 

綜合上述表現,IM特性在適用的場景下對性能的提升是非常明顯的,在消耗相對少量額外內存的條件下實現了巨大的性能提升。

 

四、IM日常維護

 

IM特性是需要不定期維護的,不僅需要關注IM中表是否加載成功,是否出現In-Memory Area不足的情況,在內存資源有限的情況下,還要優化IM中存放的表,及時添加需要的表,刪除不需要的表。此外,還可以添加或刪除IM表中的部分字段或分區,達到優化內存使用的目的。

 

1.IM添加和刪除表

 

  • 當IM特性開啟後,往in memory列式存儲中加表,命令如下:Alter table tab_name inmemory;

    注意,當執行以上命令時,Oracle並不會將表馬上存入in memory中,而是需要通過一次查詢操作觸發。

    刪除表的操作為:Alter table tab_name no inmemory;

 

  • 假如一張表有許多字段,但查詢的時候隻用到其中的某些字段,那麼,就可以隻存儲相關字段:Alter table im_table inmemory no inmemory(object_name);  --除去表的object_name字段

 

  • 假如一張表有多個分區,可以除去其中的某些分區:Alter table im_table modify partition P_201601 no inmemory;  --除去表的P_201601分區

 

2.維護常用視圖

 

>>>> 

v$inmemory_area

 

該視圖用來查看In-Memory Area內存區域的使用情況:

 

20161208101340357.jpg

 

In-Memory Area 分兩個子池,1MB POOL 用來存放列式數據,64KB POOL用來存放元數據和事務信息。POPULATE_STATUS表明當前子池加載狀態,DONE表示所有數據已經加載完畢,POPULATING表示正在加載,而OUT OF MEMORY表示分配的空間不足,需要刪表或增大In-Memory Area。

 

>>>> 

v$im_segments

 

該視圖用來查看IM中存放段的情況:

 

20161208101407496.jpg

 

可以用來查看inmemory中添加了多少表,占用多大內存空間等。

 

>>>> 

v$im_column_level

 

該試圖用來查看IM中存放的字段情況:

 

20161208101420195.jpg

 

可以看到object_name字段的inmemory_compression 顯示為no inmemory,表明該字段並未加入IM。

 

3.其他注意事項

 

由於inmemory特性的開啟是以實例為單位的,在RAC環境中,可以在不同的節點設置不同的inmemory_size, 加載不同的表,以適應不同節點訪問不同數據的業務分配機製。

 

Inmemory_size參數可以在線修改,但是必須重啟實例後才能生效,所以在啟用初期就應該規劃好,避免設置後出現內存不足、無法加表的情況。

 

Inmemory area是SGA中的一個靜態子池,占用SGA,所以在加inmemory_size 的時候應該相應調大SGA,以免擠掉其他子池的空間。

原文發布時間為:2016-12-08

本文來自雲棲社區合作夥伴DBAplus

最後更新:2017-05-11 14:31:32

  上一篇:go  當當網資深DBA:DB運維四大現代化的實現
  下一篇:go  透過DB-Enginges,看數據庫管理係統的潮起浪湧