平均提速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以兩種方式存儲數據:
IM可以對存入的表進行壓縮,壓縮級由低到高分別為:
-
NO MEMCOMPRESS
-
MEMCOMPRESS FOR DML
-
MEMCOMPRESS FOR QUERY LOW
-
MEMCOMPRESS FOR QUERY HIGH
-
MEMCOMPRESS FOR CAPACIT LOW
-
MEMCOMPRESS FOR CAPACITY HIGH
默認級別為MEMCOMPRESS FOR QUERY LOW,該級別在有效壓縮表的同時提供最佳的查詢性能,數據庫不對數據進行解壓讀取,而是采用數據字典壓縮方式,即刪除重複數據來減少內存使用。此外,其它更高的級別的壓縮方式需要對數據進行壓縮,會增加額外消耗。
二、IM特性測試
1.開啟IM特性
IM特性由inmemory_size 參數控製,隻要參數值大於0,該特性即被開啟,注意,inmemory_size 至少設置100M,否則無法啟動實例,報錯ORA-64353:
以設置inmemory_size=10g 為例:
Alter system set inmemory_size=10g sid=‘db12c1’ scope=spfile;
重啟實例後,SGA分配時會多出一項IN-Memory Area,說明IM特性已被打開。
2.IM性能測試
>>>>
全表掃描
以一張36萬行的表進行全表掃描為例:
未開啟IM:
開啟IM後:
可以看到,開啟IM後TABLE ACCESS FULL變為TABLE ACCESS INMEMORY FULL,邏輯讀從6130降為6,CPU cost由427降為17,性能有成百上千倍的提升。
>>>>
表連接查詢
im_tab_ja表有10萬條記錄,im_tab_jb表有2000多條記錄,兩表做關聯查詢測試。
未開啟IM特性:
開啟IM特性:
可以看到,IM對表關聯查詢的提升也非常明顯。
>>>>
行式存儲更優的情況
im_tab_ja有10萬條數據,在im_tab_ja表的table_name列加索引,數據離散度很高,對應的索引選擇性也就較好,此時進行全字段查詢,過濾字段為table_name。
IM 特性開啟後默認情況下執行計劃並沒有走IM的掃描:
指定執行計劃走IM:
雖然強製執行計劃走了IM,但是邏輯讀是59,遠高於默認的走索引+行式存儲的執行計劃,可見在數據離散度較高,且通過索引條件過濾的掃描場景中,IM特性對性能並沒有提升,傳統的索引+行式存儲的執行計劃已經足夠,在默認情況下還是會根據查詢索引返回rowid的方式查找數據。
3.IM壓縮比測試
>>>>
重複值對壓縮比的影響
由於IM壓縮是基於重複數據刪除的壓縮, 對300000條數據但不同數據隻有兩條的im_gender表和同樣有300000條數據但每條數據都不重複的im_table表進行壓縮測試。
im_gender 表壓縮比達3.56,而im_phone的壓縮比隻有0.98,反而增大了。由此可知,重複值高有助於提高壓縮比,而幾乎無重複值的表壓縮效果就很差。
>>>>
壓縮模式不同對壓縮比的影響
為了方便操作和對比,這裏調用了DBMS_COMPRESSION.GET_COMPRESSION_RATIO對壓縮比進行預估:
可見,壓縮比隨著壓縮等級的提升而提升,這裏選擇被壓縮的表是根據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前:
啟用IM後:
物理讀由168357多降為0,邏輯由168493降為24,cpu cost由29840降為2741,執行時間由6.65s降為0.23s, 效果顯著。
壓縮比情況:
壓縮比在默認壓縮級別下已經達到了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內存區域的使用情況:
In-Memory Area 分兩個子池,1MB POOL 用來存放列式數據,64KB POOL用來存放元數據和事務信息。POPULATE_STATUS表明當前子池加載狀態,DONE表示所有數據已經加載完畢,POPULATING表示正在加載,而OUT OF MEMORY表示分配的空間不足,需要刪表或增大In-Memory Area。
>>>>
v$im_segments
該視圖用來查看IM中存放段的情況:
可以用來查看inmemory中添加了多少表,占用多大內存空間等。
>>>>
v$im_column_level
該試圖用來查看IM中存放的字段情況:
可以看到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
上一篇:
當當網資深DBA:DB運維四大現代化的實現
下一篇:
透過DB-Enginges,看數據庫管理係統的潮起浪湧
讓Linux係統崩潰最快速的方法
《Spark官方文檔》Spark Streaming編程指南(二)
《Greenplum5.0 最佳實踐》 係統參數 <二>
設計事件驅動的微服務
獲取訪問MySQL的應用
linux查看文件夾大小、文件個數的方法
給android添加係統屬性:Settings.system和SystemProperties
Execution error: \'the function name is not a recognized built-in function name\'
ramdisk.img system.img userdata.img介紹及解包、打包方法
算法訓練-動態規劃基礎