當(dāng)前位置:首頁 > IT技術(shù) > 移動(dòng)平臺 > 正文

關(guān)于使用insert append和parallel
2021-08-10 10:16:55

為避免將來的理解沖突,本文所有說明基于Oracle 10g版本。

?

關(guān)于使用insert append

Eygle大師曾經(jīng)對insert append和logging/nologging的關(guān)系做過比較全面的測試和說明(http://www.itpub.net/thread-242761-1-1.html)。

這里不詳述了,只給出結(jié)論:

?

非歸檔模式下,不管表是否設(shè)置logging/nologging,append都會減少redo和undo的生成。

歸檔模式下,append+nologging才能減少redo和undo的生成。

?

注意在direct insert?下,實(shí)際上操作是不會對數(shù)據(jù)產(chǎn)生redo和undo的,但這不代表不會產(chǎn)生redo和undo。

?

另外在direct insert后,由于插入的數(shù)據(jù)沒有在redo中記錄,此時(shí)如果需要進(jìn)行恢復(fù),插入的記錄數(shù)據(jù)會丟失。所以在插入數(shù)據(jù)后,需要進(jìn)行全庫數(shù)據(jù)備份。

?

以append方式插入記錄后,要執(zhí)行commit,才能對表進(jìn)行查詢。否則會出現(xiàn)錯(cuò)誤:

ORA-12838:?無法在并行模式下修改之后讀/修改對象

?

另外insert append時(shí)在表上加“6”類型的鎖,會阻塞表上的所有DML語句。因此在有業(yè)務(wù)運(yùn)行的情況下要慎重使用。若同時(shí)執(zhí)行多個(gè)insert append對同一個(gè)表并行加載數(shù)據(jù),并不一定會提高速度。

?

使用append insert方法:

alter table t nologging;

insert /*+ append */ into test.t select * from test.t2;

commit;

?

關(guān)于使用parallel

可以在表級設(shè)置并行度,比如:

create table test nologging PARALLEL (DEGREE 7) as select * from dba_tables;

alter table t parallel (degree 4);

?

也可以通過SQL hint在會話級別設(shè)置,但是需要注意,如果想在執(zhí)行DML語句時(shí)使用并行(比如insert、delete、update),需要enable parallel dml,比如:

alter session enable parallel dml;

insert /*+ append?parallel(t 4)?*/ into t select * from t2;

?

順便給出我以前的2個(gè)測試結(jié)論:

實(shí)驗(yàn)1:insert時(shí)間比較

insert into t select * from t2;?(耗時(shí)00:00:12.96)

普通insert。

?

alter table t nologging;

insert /*+ append */ into t select * from t2; ?(耗時(shí)00:00:00.74)

direct insert,時(shí)間最短效率最好。

?

alter session enable parallel dml;

insert /*+ append parallel(t 4) */ into t select * from t2;?(耗時(shí)00:00:02.07)

direct insert +parallel,其實(shí)并沒有direct insert效率高,不過比普通insert好點(diǎn)。

?

實(shí)驗(yàn)2:create table + parallel產(chǎn)生UNDO測試

方法1:

create table test as select * from dba_tables;

?

方法2:

create table test nologging as select * from dba_tables;

?

方法3:

create table test nologging PARALLEL (DEGREE 7) as select * from dba_tables;

?

方法4:

create table test as select * from dba_tables where 1=0;

insert into test select * from dba_tables;

commit;

?

監(jiān)控方式:

SQL> select sid,username from v$session;

SQL> select * from v$sesstat where sid=(select sid? from v$session where username='TEST') and STATISTIC#=(select STATISTIC# from v$statname where name='undo change vector size');

?

所有測試執(zhí)行三次,結(jié)果如下:

?

?

第1次undo產(chǎn)生量(單位:bytes)

第2次

第3次

方法1(create table as select)

29212

30380

36220

方法2(nologging)

28684

26956

28640

方法3(nologging parallel)

90120

89312

91260

方法4(create table and insert data)

40660

43796

41940

?

結(jié)論:創(chuàng)建表時(shí)增加并行度會產(chǎn)生較多的undo量。

本文摘自 :https://blog.51cto.com/u

開通會員,享受整站包年服務(wù)立即開通 >