普通手段
分區,HASH-JOIN,數據倉庫函數,物化視圖,位圖索引等等為大伙在數據倉庫常用的技術,
而下面列舉的tips為項目中常用的優化手段/技巧,綠色背景highlight的部分屬於非常規手段,使用場景較為極端,需謹慎考量。
Oracle並行場景:
- SQL*Loader 的parallel參數
- 事務失敗回滾的並行處理 FAST_START_PARALLEL_ROLLBACK參數
- expdp設置parallelism參數,設置多個datapump文件
-
大批量處理+並行處理 (parallel) ,減少select次數,邏輯清晰,盡可能一次select……jion 之后再進行統一分析函數的處理,select/*+ PARALLEL(Table_Name,並行數) */統計函數 sum avgcase when then else endover(partition by order by )分析函數 lead/lag,rank,ratio_to_report,Period-over-period comparisons 等等...fromTable_Namegroup by
rollup ,cube 等等... - 創建索引、rebuild、設置並行參數(譬如大批量ETL全量時,drop索引,ETL之后再create)
- 收集統計信息的 degree參數
- 還有aleter session enable parallel dml;
insert /*+ append parallel(Table_I,並行數) */
into Table_I nologging
select /*+ PARALLEL(A,並行數) PARALLEL(B,並行數) PARALLEL(C,並行數) */
……
nologging 在DML時往往很有用
Insert、update
Insert ,update,delete 場景
1、當然最快的仍然是create table NEW_TAB as select * from OLD_TAB
1、當然最快的仍然是create table NEW_TAB as select * from OLD_TAB
2、delete的時候如果數據量過大,可以權衡考慮全量導出建立:
CREATE TABLE NEW_TAB NOLOGGING PARALLEL as select * from OLD_TAB where 條件<>要delete的數據,再truncate原表,rename重命名新表。
update也可以同理,把update的思路寫到select里面再truncate原表,rename新表。
MERGE:(同樣可以使用並行,nologging)
減少掃描表的次數,替代insert then update語句
例如:每月
計算生產庫里的會計科目成本,放入數據倉庫的事實表,但有少部分的沖銷憑證會影響近幾個月的操作。原本的total delete+insert,或是insert新數據+時間范圍內update的操作,換為merge where 時間覆蓋可能發生沖銷的范圍即可。
參數:
1、
alter session set workarea_size_policy=manual;
alter session set sort_area_size=107341824;
alter session set sort_area_retained_size=107341824;
alter session set db_file_multiblock_read_count=128;
在並行dml、並行select的ETL JOB里可以添加如上參數,10g版本似乎要重復兩次才可以生效。
db_file_multiblock_read_count配合32k、16k的大block表空間使用,針對傳統SATA盤,FC盤有效,
增加單次IO的收益。
同理,有時候反范式冗余多維度與事實表到一塊,組成長表,db_file_multiblock_read_count+32K/16K大block的性能也很好,但數據的適用場景就減少了,多數用於臨時主題分析,數據集市。
2、
修改參數 _smm_auto_min_io_size 、smm_auto_max_io_size
增大每次hash join 的內存分配大小,提升group by性能,配合大PGA使用。
3、極端環境下(或測試環境,或是同步數據的非關鍵過渡庫),打開參數 alter system set commit_write='batch,nowait'; (10gR2開始才有的特性)使得db在commit的時候,無需等待 LOG BUFFER寫出到REDO LOGFILE,即返回commit完成,需要評估災難時斷電帶來的風險,如有UPS可考慮打開。
注意:極端環境是指頻繁的commit帶來的log file sync等待成為瓶頸點的時候才考慮,才考慮!打開參數,多數情況下數據倉庫不會有這個問題。
再極端一些,還可以把Online Redo文件加大至1~2G甚至更大,關閉歸檔,減少日志切換帶來的等待,本條需要權衡場景,勿在生產環境隨意使用。
外部表
- 不能dml,不能建索引,不支持分區
- 適合只使用一次,無需修改,方便load入數據,可以並行查詢,可以Nested_Loop JOIN,可以HASH_JOIN
- 外部表結合MERGE的場景
系統級臨時表(無DML鎖,無REDO)
TRANSACTION級
SESSION級
direct path insert
物化視圖:空間換取時間
表空間遷移
可以傳輸分區表的分區,屬於物理文件級別的傳輸,不同於SQL級別,屬於最高
性能,適用於跨地區的分庫、子庫匯總至中心庫的場景。

DataStage方面的處理
1、Bulk load方式

讀端:設置 enable partitioned reads ,modulus方式分區讀取integer(zeile)

寫端:oracle connect 選擇bulk load方式
在bulk load寫入前把所有索引,主鍵等drop掉。結束后再重建。
DataStage主機在多CPU的情況下,推薦設置多個並行node進行ETL作業,輕松將IO壓到極限。

Before SQL Statement

After SQL Statement

Node的設置

多Node並行的效果如下圖:




如果在瓶頸在Datastage的Node上
(可以測試下,node的文件建立在linux的tmpfs,即/dev/shm/tmp來提速,避免在ETL過程中數據經過datastage主機的磁盤,增加io瓶頸點,主機的內存要足夠大,如64G,需測試!)
# mkdir /dev/shm/tmp
# chmod -R 777 /dev/shm/tmp
# mount --bind /dev/shm/tmp /tmp
像這樣就可以直接用/tmp 來做node文件存放使用。
考慮限制用量的情況也可以用 # mount tmpfs /tmp -t tmpfs -o size=512m
限制/tmp掛載的tmpfs只能用512m
同理,大內存主機下Oracle的 temp表空間也可以往這里放,前提是temp表空間的使用情況已經平穩,DBA能預估使用的波動范圍,並且關掉自動增長。需嚴格測試!