並行直接載入和系統調整的一點思路

dotaddjj發表於2012-07-31

並行執行一個在OLAP系統經常出現的技術,這個可以簡單描述的是處理一個sql語句時,任務被並行協調程式劃分為多個並行處理單元,然後交給相應的並行服務程式,而後並行協調程式又分配其他 的並行處理單元,直到處理完所有的單元都完成,最後協調程式把所有的並行服務處理的單位合併起為一個集合互動給客戶端。

為什麼說多用於OLAP系統了,因為OLTP系統大多都是高效的索引讀取,而高效的索引讀取

完全沒有必要開啟並行。而並行利用多個cpu單位來共享完成任務,更多用於cpu空閒的系統,

由於OLAP系統中併發較少,cpu相對比較空閒,大多是相對於報表的功能的sql,此時sql層面上很難最佳化,開啟並行是可以大幅提升sql的執行。

這裡說一下對磁碟的效能的分析,對於OLTP系統大多是索引讀取,每次IO大多單塊IO,對於OLTP系統更看重磁碟的IOPS,也就是每秒的IO次數。

OLAP系統由於大多是聚集函式報表功能,每次IO多大是fts的多塊讀取,更看重磁碟的每次IO讀取的容量,也就是最大吞吐量mbps

這裡介紹一個並行執行可以檢視並行度的檢視v$px_process

首先在session A上執行:

select /*+parallel(inf_apply_process)*/* from jhqlnwhxdb.inf_apply_process;

而後在session b上檢視開啟的並行執行程式:

SQL> select pid,server_name from v$px_process;

PID SERVER_NAME

---------- -----------

743 P006

744 P007

750 P013

738 P001

741 P004

740 P003

748 P011

745 P008

746 P009

742 P005

752 P015

737 P000

739 P002

749 P012

747 P010

751 P014

16 rows selected

SQL> show parameter cpu;

NAME TYPE VALUE

------------------------------------ -----------

cpu_count integer 8

parallel_threads_per_cpu integer 2

SQL> show parameter parallel_adaptive_multi_user;

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------

parallel_adaptive_multi_user boolean TRUE

parallel_adaptive_multi_user參數列示oracle會自動對並行度進行動態調整。還有幾個有關並行的引數parallel_min_serveroracle資料庫啟動預先分配的並行程式,parallel_max_serveroracle允許分配的最大程式數。

預設的並行度優先順序是hint>alter session force>table級別,有一點需要注意的是:

select /*+parallel(a 2)*/count(*),host from zebra.robots_article a group by host;如果hint並行,可以檢視這個sql語句有兩個步奏,一個是全表掃描的robots_article,還有一個group by hash的聚集,所以需要分配並行服務程式子程式和並行服務的父程式。有時候發現並行服務程式是並行度的二倍時就是並行服務的父程式的原因。

PX Deq Credit send blkd並行等待事件這個是經常出現於並行執行中,這個是由於並行執行時多個並行服務程式傳遞結果集給並行協調程式導致,由於並行協調程式同一時刻只能接受一個並行服務程式傳送的結果集,此時就可能會產生所謂的等待。當系統因為此並行等待事件引起系統瓶頸時,可以採取降低並行度來減少此等待事件引起的系統壓力。

經常聽見各種帖子 書籍上面都寫到在資源充足時是可以利用parallel來提高sql語句的效能的,充足如何去判斷確是一個值得斟酌的,並行度如何去設定同樣也是一個值得斟酌的,當然需要先去os上定位系統負載例如top vmstat iostat sar等強大的命令都可以對系統的負載有個簡單的瞭解,相信對os上如何診斷資源情況對於何時開啟並行還是有個比較清晰的認識的。

那麼如何設定並行度了,個人一般都是在sql語句中讓oracle自己去選擇並行度,當然也可以根據系統負載和cpu process等資訊手動設定,總是預想的是採取分解任務的思想用資源去換取時間。

直接載入append是直接把資料載入到高水位線之上,減少尋找資料塊的時間,appendnologging方式下可以減少redo的產生的,實際上由於nologging模式下,append插入redo不會記錄資料塊的修改,同樣由於是append的插入直接在HWM之上,而HWM之上的資料塊是無法檢視的,也不需要對修改的資料塊維護undo,如果rollback此時僅僅只需要維護HWM不變即可。(不過logging方式的append插入是否需要維護undo了),此時產生的undoredo僅僅只是維護資料字典 空間分配等。效率自然比平常的插入效率要高,不過由於不寫redo,這部分資料並不記錄在archivelog中。

記得有很多帖子說到如何高效插入大批次資料, 載入資料的方法很多,exp/imp expdp/impdp sql語句 sqlldr等的,不過就其基本可以採用如下並行 nologging 直接載入 禁掉索引方式插入,直接高水位或者繞過快取,nologging不寫入redo,禁掉索引較少索引的維護和期間產生的redoundo等資訊,並行利用資源換取空間。

談談對於系統調優的一點想法:對於調優其實更應該說是調整,對於系統來說,資料庫層面上的調整的收效往往是最低的,而應用的設計和需求,schemas的設計往往是最能最大程式提高系統效能的,結合合理的硬體,而dba要做的最多的應該是資料庫的備份和恢復,配合開發設計合理的應用和方案,後面的系統上線資料量起來後相對來說調整得很少,因為sql已經寫好了,程式碼和業務邏輯已經全部實現,此時大幅度修改業務邏輯和程式碼基本來說是不可能的,曾幾何時也想著資料庫調優總是可以解決n多系統瓶頸,第一次看TOM9i-10g程式設計藝術時對於資料庫也就能提高系統10%左右的效能感到非常的不理解,隨著慢慢接觸的越來越多,結合很多例項發覺這句活絕對的合理。

舉個簡單的例子:需求實時統計大表的資料量,也就是一個select count(*) from a也就是隻要有人進入某個系統的模組就能檢視相應的a表總的資料量,如果a表的資料量特別大,實時統計對於系統的壓力可想而知,大表的fts對於磁碟的IO絕對是個考驗,而如果是併發較大多個session同時執行,相信系統的負載基本是不用做別的事情了,就是等待等待,這個如果從需求層次上來說,可以一天統計一次a表的數量到臨時表b中,而讓使用者每次直接查詢select * from b即可,在業務不繁忙時對a表進行查詢寫進b表,這個對於系統來說跟前面相比簡直是區別太大了,合理的需求和設計很是重要的。

接下來就是schemas的設計,由於自己不是做資料架構的方面的,對於資料庫的schemas設計也不是很清晰,但是這個階段可以說也是非常重要的,把業務邏輯如何實現在各個物件上,往往也是提高系統效能的最直接的方法,而不要到最好各種IO等待,熱點塊,gc的同步產生的熱點快,enq併發請求等資料庫等待事件,此時dba又不得不硬著頭皮上了,物化檢視 sql調整,index的建立方式 hint寫法等,此時不得不把最後dba系統維護的階段的工作提前做了,其實往往取得效果並不明顯或者不容易取得。

囉唆了半天,資料庫是一個需要循序漸進的過程,有些話當時不理解可能到合適的時候就會忽然開朗,這裡推薦一本譚大師寫的書<<oracle跑得更快>>,個人覺得還是寫得很不錯的,適合有一定基礎的oracle愛好者反覆翻看體會作者的思想。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25362835/viewspace-1059045/,如需轉載,請註明出處,否則將追究法律責任。

相關文章