[轉]Oracle Parallel 多線程

對於一個大的任務,一般的做法是利用一個進程,串行的執行,如果系統資源足夠,可以採用parallel技術,把一個大的任務分成若干個小的任務,同時啓用n個進程/線程,並行的處理這些小的任務,這些併發的進程稱爲並行執行服務器(parallel executeion server),這些併發進程由一個稱爲併發協調進程的進程來管理。
啓用Parallel前的忠告:只有在需要處理一個很大的任務,如需要幾十分鐘,幾個小時的作業中,並且要有足夠的系統資源的情況下(這些資源包括cpu,內存,io),您才應該考慮使用parallel。否則,在一個多併發用戶下,系統本身資源負擔已經很大的情況下,啓用parallel,將會導致某一個會話試圖佔用了所有的資源,其他會話不得不去等待,從而導致系統系能反而下降的情況,一般情況下,oltp系統不要使用parallel,oltp系統中可以考慮去使用。
 
Parallel分類
l  並行查詢parallel query
l  並行dml parallel dml pdml
l  並行ddl parallel ddl pddl
 
一、 並行查詢
並行查詢允許將一個sql select語句劃分爲多個較小的查詢,每個部分的查詢併發地運行,然後將各個部分的結果組合起來,提供最終的結果,多用於全表掃描,索引全掃描等,大表的掃描和連接、創建大的索引、分區索引掃描、大批量插入更新和刪除
 
1.    啓用並行查詢
SQL> ALTER TABLE T1 PARALLEL;
告知oracle,對T1啓用parallel查詢,但並行度要參照系統的資源負載狀況來確定。
利用hints提示,啓用並行,同時也可以告知明確的並行度,否則oracle自行決定啓用的並行度,這些提示只對該sql語句有效。
SQL> select /*+ parallel(t1 8) */ count(*)from t1;
 
SQL> select degree from user_tables where table_name='T1';
DEGREE
--------------------
  DEFAULT
 
並行度爲Default,其值由下面2個參數決定
SQL> show parameter cpu
 
NAME                                TYPE       VALUE
----------------------------------------------- ------------------------------
cpu_count                           integer    2
parallel_threads_per_cpu            integer    2
 
cpu_count表示cpu數
parallel_threads_per_cpu表示每個cpu允許的並行進程數
default情況下,並行數爲cpu_count*parallel_threads_per_cpu
 
2.    取消並行設置
SQL> alter table t1 noparallel;
SQL> select degree from user_tables wheretable_name='T1';
 
DEGREE
----------------------------------------
        1
 
3.    數據字典視圖
v$px_session
sid:各個並行會話的sid
qcsid:query coordinator sid,查詢協調器sid
 
二、 並行dml
並行dml包括insert,update,delete,merge,在pdml期間,oracle可以使用多個並行執行服務器來執行insert,update,delete,merge,多個會話同時執行,同時每個會話(併發進程)都有自己的undo段,都是獨立的一個事務,這些事務要麼由pdml協調器進程提交,要麼都rollback。
在一個有充足I/o帶寬的多cpu主機中,對於大規模的dml,速度可能會有很大的提升,尤其是在大型的數據倉庫環境中。
並行dml需要顯示的啓用
SQL> alter session enable parallel dml;
 
Disable並行dml
SQL> alter session disable parallel dml;
 
三、 並行ddl
並行ddl提供了dba使用全部機器資源的能力,常用的pddl有
create table as select ……
create index
alter index rebuild
alter table move
alter table split
在這些sql語句後面加上parallel子句

SQL> alter table t1 move parallel;
Table altered
SQL> create index T1_IDX on T1 (OWNER,OBJECT_TYPE)
 2   tablespace SYSTEM
3        parallel;
4        ;


1.  用途

強行啓用並行度來執行當前SQL。這個在Oracle 9i之後的版本可以使用,之前的版本現在沒有環境進行測試。也就是說,加上這個說明,可以強行啓用Oracle的多線程處理功能。舉例的話,就像電腦裝了多核的CPU,但大多情況下都不會完全多核同時啓用(2核以上的比較明顯),使用parallel說明,就會多核同時工作,來提高效率。

但本身啓動這個功能,也是要消耗資源與性能的。所有,一般都會在返回記錄數大於100萬時使用,效果也會比較明顯。

2.  語法

/*+parallel(table_short_name,cash_number)*/

這個可以加到insert、delete、update、select的後面來使用(和rule的用法差不多,有機會再分享rule的用法)

開啓parallel功能的語句是:

alter session enable parallel dml;

這個語句是DML語句哦,如果在程序中用,用execute的方法打開。

3.  實例說明

用ERP中的transaction來說明下吧。這個table記錄了所有的transaction,而且每天數據量也算相對比較大的(根據企業自身業務量而定)。假設我們現在要查看對比去年一年當中每月的進、銷情況,所以,一般都會寫成:

select to_char(transaction_date,'yyyymm') txn_month,

       sum(

        decode(

            sign(transaction_quantity),1,transaction_quantity,0
              )

          ) in_qty,

       sum(

        decode(

            sign(transaction_quantity),-1,transaction_quantity,0
              )

          ) out_qty

  from mtl_material_transactions mmt

 where transaction_date >= add_months(

                            to_date(   

                                to_char(sysdate,'yyyy')||'0101','yyyymmdd'),

                                -12)

   and transaction_date <= add_months(

                            to_date(

                                to_char(sysdate,'yyyy')||'1231','yyyymmdd'),

                                -12)

group by to_char(transaction_date,'yyyymm')

這個SQL執行起來,如果transaction_date上面有加index的話,效率還算過的去;但如果沒有加index的話,估計就會半個小時內都執行不出來。這是就可以在select 後面加上parallel說明。例如:
select /*+parallel(mmt,10)*/
       to_char(transaction_date,'yyyymm') txn_month,

...

 

這樣的話,會大大提高執行效率。如果要將檢索出來的結果insert到另一個表tmp_count_tab的話,也可以寫成:
insert /*+parallel(t,10)*/
  into tmp_count_tab

(

    txn_month,

    in_qty,

    out_qty

)

select /*+parallel(mmt,10)*/
       to_char(transaction_date,'yyyymm') txn_month,

...

 

插入的機制和檢索機制差不多,所以,在insert後面加parallel也會加速的。關於insert機制,這裏暫不說了。
Parallel後面的數字,越大,執行效率越高。不過,貌似跟server的配置還有oracle的配置有關,增大到一定值,效果就不明顯了。所以,一般用8,10,12,16的比較常見。我試過用30,發現和16的效果一樣。不過,數值越大,佔用的資源也會相對增大的。如果是在一些package、function or procedure中寫的話,還是不要寫那麼大,免得佔用太多資源被DBA開K。
 

4.  Parallel也可以用於多表

多表的話,就是在第一後面,加入其他的就可以了。具體寫法如下:

/*+parallel(t,10) (b,10)*/

5.  小結

關於執行效率,建議還是多按照index的方法來提高效果。Oracle有自帶的explan road的方法,在執行之前,先看下執行計劃路線,對寫好的SQL tuned之後再執行。實在沒辦法了,再用parallel方法。Parallel比較邪惡,對開發者而言,不是好東西,會養成不好習慣,導致很多bad SQL不會暴漏,SQL Tuning的能力得不到提升。我有見過某些人create table後,從不create index或primary key,認爲寫SQL時加parallel就可以了。

 

(轉自:http://blog.csdn.net/jojo52013145/article/details/7460121 抱歉,原文無法查獲)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章