【DB筆試面試594】在Oracle中,關鍵字NOLOGGING、APPEND和PARALLEL提高DML性能方面有什麼差別?

  • 2019 年 10 月 10 日
  • 筆記

題目部分

在Oracle中,關鍵字NOLOGGING、APPEND和PARALLEL提高DML性能方面有什麼差別?

答案部分

眾所周知,表模式(LOGGING/NOLOGGING)、插入模式(APPEND/NOAPPEND)、資料庫運行模式(歸檔(ARCHIVELOG)/非歸檔(NOARCHIVELOG))和並行模式與DML操作的效率息息相關,作者就此設計了一個實驗,用來檢測它們不同組合生成的Redo量、Undo量和用時長短的比較,實驗結果參考表 3-22,該表數據經過多次實驗得到,表中重要數據用加粗來表示。

由於篇幅原因,有關實驗用到的建表語句、存儲過程等腳本在本書中不再列出,具體腳本可以去我的BLOG下載,下載地址為:http://blog.itpub.net/26736162/viewspace-2125815/。

表 3-22 表模式、插入模式、運行模式和並行模式的組合效率

序號

DDL/DML OPERATIONS TYPES

DDL/DML OPERATIONS

DIRECT-PATH

NOLOGGING

PARALLEL

ARCHIVELOG MODE

NOARCHIVELOG MODE

REDO

Undo

USE_TIME

REDO

Undo

USE_TIME

1

CTAS

CREATE TABLE XXX AS SELECT * FROM YYY

Y

N

N

666131564

40996

23.9

334788

42936

13.34

2

CREATE TABLE XXX NOLOGGING AS SELECT * FROM YYY

Y

Y

N

329404

41120

21.79

329272

41120

12.17

3

CREATE TABLE XXX NOLOGGING PARALLEL 4 AS SELECT * FROM YYY

Y

Y

Y

713236

157200

7.39

710340

156708

7.27

4

CI

CREATE INDEX XXX

N

N

N

101420764

21336

12.24

267116

20896

17.84

5

CREATE INDEX XXX NOLOGGING

N

Y

N

267744

20896

14.08

267048

20896

17.41

6

CREATE INDEX XXX NOLOGGING PARALLEL 4

N

Y

Y

475836

110576

5.62

475624

111352

5

7

MOVE

ALTER TABLE XXX MOVE;

N

N

N

651251072

36048

14.58

418756

36048

18.05

8

ALTER TABLE XXX MOVE NOLOGGING;

N

Y

N

352980

36092

12.35

358256

37848

13.09

9

ALTER TABLE XXX MOVE NOLOGGING PARALLEL 4;

N

Y

Y

661096

134760

5.06

654360

132800

4.29

10

INSERT

INSERT INTO XXX SELECT * FROM YYY

N

N

N

661223364

21352708

21.86

661245624

21353812

25.23

11

ALTER TABLE XXX NOLOGGING;INSERT INTO XXX SELECT * FROM YYY;

N

Y

N

647831988

21334768

60.64

647827568

21334984

54.89

12

INSERT /*+ APPEND */ INTO XXX SELECT * FROM YYY

Y

N

N

666203072

2132

17.68

142232

2132

12.54

13

ALTER TABLE XXX NOLOGGING;INSERT /*+ APPEND */ INTO XXX SELECT * FROM YYY

Y

Y

N

132080

80

20.82

132036

80

17.65

14

ALTER TABLE XXX NOLOGGING;INSERT /*+ PARALLEL(4) APPEND */ INTO XXX SELECT * FROM YYY

Y

Y

Y

131948

80

11.92

131948

80

10.4

15

ALTER TABLE XXX NOLOGGING;ALTER SESSION ENABLE PARALLEL DML;INSERT /*+ PARALLEL(4) APPEND */ INTO XXX SELECT * FROM YYY

Y

Y

Y(PDML)

131992

80

11.73

131904

80

11.43

16

UPDATE

UPDATE XXX SET

N

N

N

20188804

7494096

20.44

6108008

2910892

13.81

17

UPDATE /*+ PARALLEL(4) */ XXX SET

N

N

Y(Queries)

6109168

2911640

24.57

6120040

2914976

25.77

18

ALTER TABLE XXX NOLOGGING;UPDATE XXX SET

N

Y

N

20434668

7570448

20.61

20694012

7651184

21.5

19

ALTER TABLE XXX NOLOGGING;UPDATE /*+ PARALLEL(4) */ XXX SET

N

Y

Y(Queries)

22259628

8139204

27.82

6119332

2914676

26.36

20

ALTER SESSION ENABLE PARALLEL DML;UPDATE /*+ PARALLEL(4) */ XXX SET

N

N

Y(PDML)

21960940

8046532

30.48

19796852

7371352

27.88

21

ALTER TABLE XXX NOLOGGING;ALTER SESSION ENABLE PARALLEL DML;UPDATE /*+ PARALLEL(4) */ XXX SET

N

Y

Y(PDML)

22318520

8157968

29.63

6120048

2914972

26.99

22

MERGE

ALTER TABLE XXX NOLOGGING;MERGE INTO XXX T USING YYY

N

Y

N

15790172

5582028

24.56

15790084

5581788

23.33

23

ALTER TABLE XXX NOLOGGING;MERGE /*+ PARALLEL(4) */ INTO XXX T USING YYY

N

Y

Y(Queries)

15793248

5582028

6.86

15791808

5581612

8.37

24

ALTER TABLE XXX NOLOGGING;ALTER SESSION ENABLE PARALLEL DML;MERGE /*+ PARALLEL(4) */ INTO XXX T USING YYY

N

Y

Y(PDML)

15793004

5582020

6.84

15792800

5581876

8.31

25

DELETE

DELETE XXX;

N

N

N

23517296

14352556

13.39

23508340

14349412

19.57

26

DELETE /*+PARALLEL(4) */ XXX;

N

N

Y(Queries)

23517240

14352612

5.05

23507248

14348364

4.47

27

ALTER TABLE XXX NOLOGGING;DELETE FROM XXX;

N

Y

N

23513944

14350336

13.61

23504352

14346304

19.31

28

ALTER TABLE XXX NOLOGGING;DELETE /*+PARALLEL(4) */ FROM XXX;

N

Y

Y(Queries)

23517240

14352440

5.07

23508668

14349436

4.63

29

ALTER SESSION ENABLE PARALLEL DML;DELETE /*+PARALLEL(4) */ FROM XXX;

N

N

Y(PDML)

23517256

14352464

5.44

23508668

14349444

7.68

30

ALTER TABLE XXX NOLOGGING;ALTER SESSION ENABLE PARALLEL DML;DELETE /*+PARALLEL(4) */ FROM XXX;

N

Y

Y(PDML)

23513320

14349892

5.66

23504200

14346304

4.52

根據表 3-6的數據可以得到如下的結論:

(一)關於效率的結論:

1、 INSERT INTO在有APPEND提示的情況下,只要NOLOGGING或NOARCHIVELOG滿足一個條件即可產生少量的Redo和Undo。另外,PARALLEL默認是以DIRECT的方式進行載入數據的,一般在並行情況下SQL執行速度有所提高。

2、 CTAS:CTAS本身就是一種DIRECT的操作,歸檔模式和NOLOGGING模式組合可以產生少量Redo。在並行模式下執行時間大幅度減少,但生成的Redo和Undo成倍增長。

3、 ALTER TABLE … MOVE:歸檔模式和NOLOGGING模式組合可以產生少量Redo。在並行模式下執行時間大幅度減少,但生成的Redo和Undo成倍增長。

4、 CREATE INDEX:歸檔模式和NOLOGGING模式組合可以產生少量Redo。在並行模式下執行時間大幅度減少,但生成的Redo和Undo成倍增長。

5、 UPDATE:任何組合都會生成大量Undo、大量Redo。有關並行的性能需要查詢執行計劃再做定奪。

6、 DELETE:任何組合都會生成大量Undo、大量Redo。加上並行可以大幅度提高SQL的執行速度。

7、 MERGE:在關聯更新的情況下,MERGE語句的非關聯形式的性能比UPDATE要高,若加上並行性能更好。

8、 總體而言,非歸檔比歸檔模式下性能高。

(二)關於屬性NOLOGGING和並行度的結論:

1、對於形如:「CREATE TABLE TT NOLOGGING PARALLEL 4 AS SELECT * FROM DBA_OBJECTS;」或「CREATE INDEX IDNX11 ON TT(OBJECT_ID) NOLOGGING PARALLEL 4;」的SQL語句而言,創建的表或索引的並行度是4,日誌模式是NOLOGGING,所以,生產庫上對於重要的表和索引需要修改為LOGGING,並行度可以根據需要來修改,SQL語句為:「ALTER TABLE TT LOGGING NOPARALLEL;」或「ALTER INDEX IDNX11 LOGGING NOPARALLEL;」。

2、對於形如:「ALTER TABLE TT MOVE NOLOGGING PARALLEL 4;」或「ALTER INDEX IDNX11 REBUILD NOLOGGING PARALLEL 4;」的SQL語句而言,執行後的表的並行度依然為原來的並行度,但是索引的並行度是4,而日誌模式都是NOLOGGING。

總之,若執行了如上形式的SQL語句後,最好都修改一下表或索引的並行度及其日誌模式。

(三)APPEND使用注意事項:

1、建議不要經常使用APPEND,這樣會使表一直處於高水位之上,除非這個表只插入數據而不刪除數據。

2、以APPEND方式插入記錄後,要執行COMMIT,才能對錶進行查詢。否則會出現錯誤:ORA-12838: 無法在並行模式下修改之後讀/修改對象。

3、APPEND對INSERT INTO … VALUES語句不起作用,需要使用Oracle 11gR2的APPEND_VALUES來提示才可以直接路徑載入,注意:APPEND_VALUES對INSERT INTO … SELECT也起作用。

4、APPEND使用高水位之上的塊,減少了搜索FREELIST上塊的時間。

5、在歸檔模式下,NOLOGGING和APPEND組合才會顯著減少Redo數量。在非歸檔模式下,單獨APPEND即可減少Redo數量。需要注意的是,在NOLOGGING加APPEND組合操作後,需要對全表做備份,否則如果後期在執行了RESTORE加RECOVER操作後,資料庫會報「ORA-26040」的錯誤。

6、APPEND不會減少相關表的索引上產生的Redo數量。

7、APPEND的插入操作在表上加6級排它鎖,會阻塞表上的所有DML語句。

8、每提交一次,就會取一個新的BLOCK存放,高水位就上推一個BLOCK,若在LOOP循環中,外部循環100W次,但是每循環一次只有一行符合條件的數據插入,這樣,大量單條/*+ APPEND*/插入,就會使得表空間急劇增大,除對INSERT本身造成性能影響之外,對以後的SELECT、UPDATE、DELETE更是帶來更巨大的性能影響。

(四)NOLOGGING使用注意事項:

1、NOLOGGING方式插入數據後最好對錶做個備份。生產上重要的表不建議設置NOLOGGING屬性。

2、如果庫處在FORCE LOGGING模式下,那麼此時的NOLOGGING方式是無效的。

3、NOLOGGING模式下,只有在如下幾種情況下資料庫操作才不產成Redo記錄

l 索引的創建和ALTER(重建)。對於形如「CREATE INDEX IND_TEST_LHR_LOG ON TEST_LHR(ID) NOLOGGING;」的SQL語句創建的索引,不管表的日誌是處在NOLOGGING還是LOGGING狀態下,都會產生很少的Redo日誌。

l 表的批量INSERT(通過提示使用「直接路徑插入」,或採用SQL*Loader直接路徑載入),表數據不生成Redo,但是所有索引修改會生成Redo。

l LOB操作(對大對象的更新不必生成日誌)。

l 通過CREATE TABLE AS SELECT創建表。

l 各種ALTER TABLE操作,例如MOVE和SPLIT等。

4、事實上,在NOLOGGING模式下,還是會生成一定數量的Redo。這些Redo的作用是保護數據字典,這是不可避免的。

5、NOLOGGING不能避免所有後續操作不生成Redo。例如創建表(CREATE TABLE)這個操作沒有生成日誌,但是所有後續的增、刪、改操作(例如INSERT、DELETE和UPDATE等)還是會生成Redo日誌,其它特殊的操作(例如使用SQL*Loader的直接路徑載入,或使用INSERT直接路徑插入)不生成日誌。不過,一般而言,應用對這個表執行的操作都會生成日誌。

(五)Oracle中的並行

首先,Oracle會創建一個進程用於協調並行服務進程之間的資訊傳遞,這個協調進程將需要操作的數據集(例如表的數據塊)分割成很多部分,稱為並行處理單元,然後並行協調進程給每個並行進程分配一個數據單元。例如有四個並行服務進程,它們就會同時處理各自分配的單元,當一個並行服務進程處理完畢後,協調進程就會給它們分配另外的單元,如此反覆,直到表上的數據都處理完畢,最後協調進程負責將每個小的集合合併為一個大集合作為最終的執行結果,返回給用戶。並行處理的機制實際上就是把一個要掃描的數據集分成很多小數據集,Oracle會啟動幾個並行服務進程同時處理這些小數據集,最後將這些結果匯總,作為最終的處理結果返回給用戶。

這種數據並行處理方式在OLAP系統中非常有用,OLAP系統的表通常來說都非常大,如果系統的CPU比較多,那麼可以讓所有的CPU共同來處理這些數據,效果就會比串列執行要好得多。對於OLTP系統,通常而言,並行並不合適,原因是OLTP系統上幾乎在所有的SQL操作中,數據訪問路徑基本上以索引訪問為主,並且返回結果集非常小,這樣的SQL操作的處理速度一般非常快,不需要啟用並行。

使用並行方式,不論是創建表,還是修改表、創建索引、重建索引,它們的機制都是一樣的,那就是Oracle給每個並行服務進程分配一塊空間,每個進程在自己的空間里處理數據,最後將處理完畢的數據匯總,完成SQL的操作。

1. 並行執行的使用範圍

Oracle的並行技術在下面的場景中可以使用:

(1)PARALLEL QUERY(並行查詢,簡稱PQ)。

(2)PARALLEL DDL(並行DDL操作,簡稱PDDL,例如建表、建索引等)。

(3)PARALLEL DML(並行DML操作,簡稱PDML,例如INSERT、UPDATE、DELETE等)。

2. 並行查詢(PQ)

並行查詢可以在查詢語句、子查詢語句中使用,但是不可以使用在一個遠程引用的對象上(例如DBLINK)。當一條SQL語句發生全表掃描、全分區掃描及索引快速全掃描的時候,若優化器滿足下面的條件之一就可以使用並行處理:

① 會話級別,會話設置了強制並行,例如,「ALTER SESSION FORCE PARALLEL QUERY PARALLEL 4;」,執行「SELECT COUNT(*) FROM TB_PART_LHR;」,這裡的TB_PART_LHR為分區表。

② 語句級別,SQL語句中有Hint提示,例如,使用PARALLEL或者PARALLEL_INDEX。如,「SELECT /*+ PARALLEL(T 4) */ FROM T;」。

③ SQL語句中引用的對象被設置了並行屬性。在表和索引的定義中增加並行度屬性,該屬性可以在創建表和索引時設置,也可對已創建的表和索引的並行度屬性進行修改。例如,「ALTER TABLE TB_NAME PARALLEL 4;」、「ALTER TABLE TB_NAME PARALLEL (DEGREE DEFAULT);」。取消表或索引的並行度的SQL為:「ALTER TABLE TB_NAME NOPARALLEL;」。示例如下:

SYS@orclasm > ALTER TABLE SH.SALES PARALLEL (DEGREE 10);    Table altered.    SYS@orclasm >  SELECT DEGREE FROM DBA_TABLES WHERE TABLE_NAME='SALES' AND OWNER='SH';    DEGREE  --------------------          10    SYS@orclasm > ALTER TABLE SH.SALES PARALLEL (DEGREE DEFAULT);    Table altered.    SYS@orclasm > SELECT DEGREE FROM DBA_TABLES WHERE TABLE_NAME='SALES' AND OWNER='SH';    DEGREE  --------------------     DEFAULT    SYS@orclasm >  ALTER TABLE  SH.SALES NOPARALLEL;    Table altered.    SYS@orclasm > SELECT DEGREE FROM DBA_TABLES WHERE TABLE_NAME='SALES' AND OWNER='SH';    DEGREE  --------------------           1    SYS@orclasm > CREATE TABLE SCOTT.AA AS SELECT * FROM DUAL;    Table created.    SYS@orclasm >  SELECT DEGREE FROM DBA_TABLES WHERE TABLE_NAME='AA' AND OWNER='SCOTT';    DEGREE  --------------------           1  

在日常使用上,一般不建議在對象級別定義並行度,因為這會導致相關對象的操作都變為並行處理,而並行處理會佔用大量的CPU資源,導致資料庫整體性能失控。一般在會話或語句級別進行處理。

1. 一些參數

和並行相關的參數較多,下面給出幾個常見的參數,其它參數請參考官方文檔:

l PARALLEL_MIN_SERVERS:默認值為0,確定實例上並行執行進程的最小數,該值是Oracle實例啟動時創建的並行執行進程的數目,可以使用「 ps -ef|grep ora_p0」來查看。Oracle RAC多個實例可以有不同的值。若修改了該值,則只有當資料庫實例重啟的情況下後台進程數才會變化。

l PARALLEL_MAX_SERVERS:默認值為PARALLEL_THREADS_PER_CPU * CPU_COUNT * concurrent_parallel_users * 5。該參數確定一個實例並行執行進程和並行恢復進程的最大數。當需求增加時,Oracle資料庫從實例啟動時的進程數增加到該參數值。在默認值計算公式中,實例上賦予正在使用的concurrent_parallel_users的值和記憶體管理設置相關。如果自動記憶體管理被關閉(手工模式),那麼concurrent_parallel_users為1。如果PGA自動記憶體管理被開啟,那麼concurrent_parallel_users的值為2.如果除了PGA自動記憶體管理,全局記憶體管理或SGA記憶體目標也被使用,那麼,concurrent_parallel_users為4。Oracle RAC多個實例可以有不同值。

l PARALLEL_MIN_TIME_THRESHOLD:確定一個語句被考慮採用自動並行度前一個語句將用的最小執行時間。默認值為AUTO,表示10s。只有PARALLEL_DEGREE_POLICY被設置為AUTO或LIMITED時,自動並行度才被開啟。

l PARALLEL_DEGREE_POLICY:該參數確定是否開啟自動並行度,語句排隊和記憶體並行執行。包括MANUAL、LIMITIED和AUTO,默認值為MANUAL。如果一個PARALLEL Hint在語句級被使用,那麼無論PARALLEL_DEGREE_POLICY值被設置成什麼,自動並行度都將被開啟。注意:該參數盡量不要修改為AUTO,因為相關的Bug較多,一般使用MANUAL即可。

n MANUAL:關閉自動並行度,語句排隊和記憶體並行執行。這恢復並行執行到11.2之前的行為。這是默認設置。

n LIMITED:對某些語句開啟自動並行執行,但語句排隊和記憶體並行執行被關閉。自動並行度僅僅適用那些存取顯式用PARALELL語句標示默認並行度的表或索引的語句。並不存取這些被顯式標示默認並行度的表或索引的語句將保持手工(MANUAL)行為。

n AUTO:開啟自動並行度,語句排隊和記憶體並行執行。

2. I/O Calibration和DOP的關係

從Oracle 11.2.0.2開始,只有當I/O Calibration(I/O 校準、I/O統計資訊)被收集才能使用自動並行度(DOP,Automatic Degree of Parallelism)。當PARALLEL_DEGREE_POLICY被設置為AUTO時,Oracle資料庫將會基於執行計劃中操作的成本和硬體特性來判斷是否使用並行。如果一個PARALLEL Hint在語句級被使用,那麼無論PARALLEL_DEGREE_POLICY的值設置成什麼,自動並行度都將被開啟。

若沒有收集I/O Calibration統計數據,則在執行計劃的Note部分可以看到「automatic DOP: skipped because of IO calibrate statistics are missing」這樣的資訊。若使用了DOP,則可以在執行計劃的Note部分可以看到類似於「automatic DOP: Computed Degree of Parallelism is 2」的資訊。

Oracle提供了PL/SQL包DBMS_RESOURCE_MANAGER.CALIBRATE_IO來收集I/O Calibration的統計數據。收集I/O Calibration統計數據的持續時間由NUM_DISKS變數與RAC中節點數決定的。視圖V$IO_CALIBRATION_STATUS可以查詢是否收集了I/O Calibration統計數據。若沒有收集I/O Calibration,則可以使用如下的存儲過程來收集:

SET SERVEROUTPUT ON  DECLARE     lat INTEGER;     iops INTEGER;     mbps INTEGER;  BEGIN      --DBMS_RESOURCE_MANAGER.CALIBRATE_IO(, ,iops, mbps, lat);      DBMS_RESOURCE_MANAGER.CALIBRATE_IO (1, 10, iops, mbps, lat);     DBMS_OUTPUT.PUT_LINE ('max_iops = ' || iops);     DBMS_OUTPUT.PUT_LINE ('latency = ' || lat);     dbms_output.put_line('max_mbps = ' || mbps);  END;  /  

注意,DBMS_RESOURCE_MANAGER.CALIBRATE_IO的前兩個參數分別為num_disks和max_latency是輸入變數,並且有三個輸出變數。

num_disks:為了獲得最精確的結果,最好提供資料庫所使用的真實物理磁碟數。如果是使用ASM來管理資料庫文件,那麼就是指存儲數據的磁碟組,那麼只有存儲數據的磁碟組中的物理磁碟作為num_disks變數值,不包含FRA磁碟組中的物理磁碟。

latency:對資料庫塊I/O操作允許的最大延遲。

1. 並行DDL操作(PDDL)

表或索引的CREATE或ALTER操作可以使用並行。例如,以下表操作可以使用並行執行:

l 建表:CREATE TABLE … AS SELECT(CTAS)

l 表移動:ALTER TABLE … MOVE

l 表分區移動:ALTER TABLE … MOVE PARTITION

l 表分區並行分解:ALTER TABLE … SPLIT PARTITION

l 表分區並行合併:ALTER TABLE … COALESCE PARTITION

l 創建和校驗約束:ALTER TABLE … ADD CONSTRAINT

l 創建索引:CREATE INDEX

l 重建索引:ALTER INDEX … REBULD

l 重建索引分區:ALTER INDEX … REBULD PARTITION

l 索引分區的分解:ALTER INDEX … SPLIT PARTITION

2. 並行DML操作(PDML)

Oracle可以對DML操作使用並行執行。如果要讓DML操作使用並行執行,那麼必須顯式地在會話里執行如下命令:

ALTER SESSION ENABLE PARALLEL DML;  

只有執行了這個命令,Oracle才會對之後符合併行條件的DML操作並行執行,如果沒有這個設定,那麼即使SQL中指定了並行執行,Oracle也會忽略它。

以下給出一個並行UPDATE的示例:

LHR@TEST> CREATE TABLE TB_LHR20160518 AS  SELECT * FROM DBA_OBJECTS;  Table created.  LHR@TEST> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL,NULL,'BASIC +PARALLEL'));  PLAN_TABLE_OUTPUT  -----------------------------------------------------------------------------------  Plan hash value: 2194116729  -----------------------------------------------------------------------------  | Id  | Operation             | Name           |    TQ  |IN-OUT| PQ Distrib |  -----------------------------------------------------------------------------  |   0 | UPDATE STATEMENT      |                |        |      |            |  |   1 |  UPDATE               | TB_LHR20160518 |        |      |            |  |   2 |   PX COORDINATOR      |                |        |      |            |  |   3 |    PX SEND QC (RANDOM)| :TQ10000       |  Q1,00 | P->S | QC (RAND)  |  |   4 |     PX BLOCK ITERATOR |                |  Q1,00 | PCWC |            |  |   5 |      TABLE ACCESS FULL| TB_LHR20160518 |  Q1,00 | PCWP |            |  -----------------------------------------------------------------------------  12 rows selected.  LHR@TEST> EXPLAIN PLAN FOR UPDATE /*+ PARALLEL (T1,4) */ TB_LHR20160518 T1 SET OBJECT_NAME='LHR';  Explained.  LHR@TEST> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL,NULL,'BASIC +PARALLEL'));  PLAN_TABLE_OUTPUT  --------------------------------------------------------------------------------  Plan hash value: 2194116729  -----------------------------------------------------------------------------  | Id  | Operation             | Name           |    TQ  |IN-OUT| PQ Distrib |  -----------------------------------------------------------------------------  |   0 | UPDATE STATEMENT      |                |        |      |            |  |   1 |  UPDATE               | TB_LHR20160518 |        |      |            |  |   2 |   PX COORDINATOR      |                |        |      |            |  |   3 |    PX SEND QC (RANDOM)| :TQ10000       |  Q1,00 | P->S | QC (RAND)  |  |   4 |     PX BLOCK ITERATOR |                |  Q1,00 | PCWC |            |  |   5 |      TABLE ACCESS FULL| TB_LHR20160518 |  Q1,00 | PCWP |            |  -----------------------------------------------------------------------------  12 rows selected.  LHR@test> ALTER SESSION ENABLE  PARALLEL DML;  Session altered.  LHR@TEST> EXPLAIN PLAN FOR UPDATE /*+ PARALLEL (T1,4) */ TB_LHR20160518 T1 SET OBJECT_NAME='LHR';  Explained.  LHR@TEST> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL,NULL,'BASIC +PARALLEL'));  PLAN_TABLE_OUTPUT  ----------------------------------------------------------------------------------  Plan hash value: 3729706116  -----------------------------------------------------------------------------  | Id  | Operation             | Name           |    TQ  |IN-OUT| PQ Distrib |  -----------------------------------------------------------------------------  |   0 | UPDATE STATEMENT      |                |        |      |            |  |   1 |  PX COORDINATOR       |                |        |      |            |  |   2 |   PX SEND QC (RANDOM) | :TQ10000       |  Q1,00 | P->S | QC (RAND)  |  |   3 |    UPDATE             | TB_LHR20160518 |  Q1,00 | PCWP |            |  |   4 |     PX BLOCK ITERATOR |                |  Q1,00 | PCWC |            |  |   5 |      TABLE ACCESS FULL| TB_LHR20160518 |  Q1,00 | PCWP |            |  -----------------------------------------------------------------------------  12 rows selected.  

通過執行計劃可以看出,只有執行了「ALTER SESSION ENABLE PARALLEL DML;」後,UPDATE操作才真正地實現了並行操作,如果不執行該語句,那麼只是執行了並發查詢,並沒有實現並發更新操作。

下表列出了這3種並行處理方式的開啟及禁用語句:

類別

區別

並行查詢(PQ)

默認

開啟

查詢

SELECT D.PQ_STATUS FROM V$SESSION D WHERE D.SID=USERENV('sid');

啟用、禁用

ALTER SESSION ENABLE PARALLEL QUERY; –啟用ALTER SESSION FORCE PARALLEL QUERY PARALLEL n; –強制開啟ALTER SESSION DISABLE PARALLEL QUERY; –禁用

並行DDL(PDDL)

默認

開啟

查詢

SELECT D.PDDL_STATUS FROM V$SESSION D WHERE D.SID=USERENV('sid');

啟用、禁用

ALTER SESSION ENABLE PARALLEL DDL; –啟用ALTER SESSION FORCE PARALLEL DDL PARALLEL n; –強制開啟ALTER SESSION DISABLE PARALLEL DDL; –禁用

並行DML(PDML)

默認

關閉

查詢

SELECT D.PDML_STATUS FROM V$SESSION D WHERE D.SID=USERENV('sid');

啟用、禁用

ALTER SESSION ENABLE PARALLEL DML; –啟用ALTER SESSION FORCE PARALLEL DML PARALLEL n; –強制開啟ALTER SESSION DISABLE PARALLEL DML; –禁用

7. RAC中的並行

如果連接Oracle RAC資料庫,那麼一個節點上的並發操作可以分布到多個節點上同時執行。可以使用視圖GV$PX_SESSION查詢並行會話的進程。有關RAC可以參考【3.2.16 RAC維護】。

這是一個Oracle 11g的RAC環境,下面建立一張測試表,建立過程中設置表的並行度:

[ZFWWLHRDB1:oracle]:/oracle>ORACLE_SID=raclhr1  [ZFWWLHRDB1:oracle]:/oracle>sqlplus / as sysdba  SQL*Plus: Release 11.2.0.4.0 Production on Fri Sep 30 14:52:23 2016  Copyright (c) 1982, 2013, Oracle.  All rights reserved.  Connected to:  Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production  With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,  Data Mining and Real Application Testing options  SYS@raclhr1> show parameter cluster  NAME                                 TYPE        VALUE  ------------------------------------ ----------- ------------------------------  cluster_database                     boolean     TRUE  cluster_database_instances           integer     2  cluster_interconnects                string  SYS@raclhr1> CREATE TABLE T_PARALLEL_LHR NOLOGGING PARALLEL 4    2   AS SELECT A.* FROM DBA_OBJECTS A, DBA_TABLES    3   WHERE ROWNUM <= 5000000;  Table created.  SYS@raclhr1> SELECT * FROM V$MYSTAT WHERE ROWNUM<=1;         SID STATISTIC#      VALUE  ---------- ---------- ----------         167          0          0  SYS@raclhr1> set autot on  SYS@raclhr1> SET LINESIZE 9999  SYS@raclhr1> SET PAGESIZE 9999  SYS@raclhr1> SELECT COUNT(*) FROM T_PARALLEL_LHR a,T_PARALLEL_LHR b where rownum<=1000000;    COUNT(*)  ----------     1000000  Execution Plan  ----------------------------------------------------------  Plan hash value: 1691788013  -------------------------------------------------------------------------------------------------------------------  | Id  | Operation                   | Name           | Rows  | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |  -------------------------------------------------------------------------------------------------------------------  |   0 | SELECT STATEMENT            |                |     1 |  2057M  (5)|999:59:59 |        |      |            |  |   1 |  SORT AGGREGATE             |                |     1 |            |          |        |      |            |  |*  2 |   COUNT STOPKEY             |                |       |            |          |        |      |            |  |   3 |    PX COORDINATOR           |                |       |            |          |        |      |            |  |   4 |     PX SEND QC (RANDOM)     | :TQ10001       |    23T|  2057M  (5)|999:59:59 |  Q1,01 | P->S | QC (RAND)  |  |*  5 |      COUNT STOPKEY          |                |       |            |          |  Q1,01 | PCWC |            |  |   6 |       MERGE JOIN CARTESIAN  |                |    23T|  2057M  (5)|999:59:59 |  Q1,01 | PCWP |            |  |   7 |        PX BLOCK ITERATOR    |                |  4857K|  5396   (1)| 00:01:05 |  Q1,01 | PCWC |            |  |   8 |         TABLE ACCESS FULL   | T_PARALLEL_LHR |  4857K|  5396   (1)| 00:01:05 |  Q1,01 | PCWP |            |  |   9 |        BUFFER SORT          |                |  4857K|  2057M  (5)|999:59:59 |  Q1,01 | PCWP |            |  |  10 |         PX RECEIVE          |                |  4857K|  5396   (1)| 00:01:05 |  Q1,01 | PCWP |            |  |  11 |          PX SEND BROADCAST  | :TQ10000       |  4857K|  5396   (1)| 00:01:05 |  Q1,00 | P->P | BROADCAST  |  |  12 |           PX BLOCK ITERATOR |                |  4857K|  5396   (1)| 00:01:05 |  Q1,00 | PCWC |            |  |  13 |            TABLE ACCESS FULL| T_PARALLEL_LHR |  4857K|  5396   (1)| 00:01:05 |  Q1,00 | PCWP |            |  -------------------------------------------------------------------------------------------------------------------  Predicate Information (identified by operation id):  ---------------------------------------------------     2 - filter(ROWNUM<=1000000)     5 - filter(ROWNUM<=1000000)  Note  -----     - dynamic sampling used for this statement (level=4)  Statistics  ----------------------------------------------------------          112  recursive calls            8  db block gets        72078  consistent gets        74257  physical reads            0  redo size          526  bytes sent via SQL*Net to client          520  bytes received via SQL*Net from client            2  SQL*Net roundtrips to/from client            0  sorts (memory)            4  sorts (disk)            1  rows processed  

從執行計劃可以看到,Oracle選擇了並行執行。

新建立一個會話,在執行上面這個並行查詢的同時查詢GV$PX_SESSION(或GV$PX_PROCESS)視圖:

SYS@raclhr1> SELECT * FROM GV$PX_SESSION WHERE QCSID=167;     INST_ID SADDR                   SID    SERIAL#      QCSID  QCSERIAL#  QCINST_ID SERVER_GROUP SERVER_SET    SERVER#     DEGREE REQ_DEGREE  ---------- ---------------- ---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ----------           1 07000100538364A0        199         35        167          5          1            1          1          1          4          4           1 0700010053894FC0        230         35        167          5          1            1          1          2          4          4           1 0700010053607480         10         37        167          5          1            1          2          1          4          4           1 070001005366F240         38          3        167          5          1            1          2          2          4          4           1 07000100537DAA60        167          5        167           2 070001005383F740        196         43        167          5          1            1          1          3          4          4           2 07000100536D3F20         67          9        167          5          1            1          1          4          4          4           2 07000100536168E0          5          5        167          5          1            1          2          3          4          4           2 07000100536784E0         35        113        167          5          1            1          2          4          4          4  9 rows selected.  

很顯然,並行查詢的4個進程已經分布到兩個節點上同時執行了,每個節點上創建4個並行從屬進程。

& 說明:

有關Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,Redo、Undo和執行速度的比較具體操作過程可以參考我的BLOG:http://blog.itpub.net/26736162/viewspace-2125815/

有關什麼是I/O Calibration的更多內容可以參考我的BLOG:http://blog.itpub.net/26736162/viewspace-2148709/

有關Oracle中並行的的更多內容可以參考我的BLOG:http://blog.itpub.net/26736162/viewspace-2149240/

本文選自《Oracle程式設計師面試筆試寶典》,作者:李華榮。