1. append方式新增記錄對insert into ... values語句不起作用。

2. 以append方式批次插入的記錄,其儲存位置在hwm 之上,即使hwm之下存在空閒塊也不能使用。

3. 以append方式插入記錄後,要執行commit,才能對錶進行查詢。否則會出現錯誤:

ORA-12838: 無法在並行模式下修改之後讀/修改物件

4. 在歸檔模式下,要把表設定為nologging,然後以append方式批次新增記錄,才會顯著減少redo數量。在非歸檔模式下,不必設定表的nologging屬性,即可減少redo數量。如果表上有索引,則append方式批次新增記錄,不會減少索引上產生的redo數量,索引上的redo數量可能比表的redo數量還要大。

用insert append可以實現直接路徑載入,速度比常規載入方式快。但有一點需要注意: insert append時在表上加“6”型別的鎖,會阻塞表上的所有DML語句。因此在有業務執行的情況下要慎重使用。若同時執行多個insert append對同一個表並行載入資料,並不一定會提高速度。因為每一時刻只能有一個程式在載入(排它鎖造成)。

SQL> create table test as select * from dba_objects where 1=2;

表已建立。

SQL> insert into test select * from dba_objects;

已建立11344行。

SQL> set lines 150
SQL> col object_type for a10
SQL> col object for a30
SQL> col username for a10
SQL> col osuser for a10
SQL> col program for a30
SQL> col sid for 99,999
SQL> col locked_mode for 99
SQL> col spid for 999,999
SQL> select o.object_type,o.owner||'.'||o.object_name object,s.sid,s.serial#,p.spid,s.username,s.osuser,s.program,l.lock
ed_mode
2 from v$locked_object l,dba_objects o,v$session s,v$process p
3 where l.object_id = o.object_id
4 and s.sid=l.session_id
5 and s.paddr=p.addr
6 and o.object_name = upper('&obj');
輸入 obj 的值: test
原值 6: and o.object_name = upper('&obj')
新值 6: and o.object_name = upper('test')

OBJECT_TYP OBJECT SID SERIAL# SPID USERNAME OSUSER PROGRAM
LOCKED_MODE
---------- ------------------------------ ------- ---------- ------------ ---------- ---------- ------------------------
------ -----------
TABLE SYS.TEST 147 19 784 SYS CNPEKALT02 sqlplus.exe
3
2jyu
可以看到,insert 時在表上加的是“3”型別的鎖。

SQL> rollback;

回退已完成。

SQL> insert /*+ append */ into test select * from dba_objects;

已建立11344行。

SQL> set lines 150
SQL> col object_type for a10
SQL> col object for a30
SQL> col username for a10
SQL> col osuser for a10
SQL> col program for a30
SQL> col sid for 99,999
SQL> col locked_mode for 99
SQL> col spid for 999,999
SQL> select o.object_type,o.owner||'.'||o.object_name object,s.sid,s.serial#,p.spid,s.username,s.osuser,s.program,l.lock
ed_mode
2 from v$locked_object l,dba_objects o,v$session s,v$process p
3 where l.object_id = o.object_id
4 and s.sid=l.session_id
5 and s.paddr=p.addr
6 and o.object_name = upper('&obj');
輸入 obj 的值: test
原值 6: and o.object_name = upper('&obj')
新值 6: and o.object_name = upper('test')

OBJECT_TYP OBJECT SID SERIAL# SPID USERNAME OSUSER PROGRAM
LOCKED_MODE
---------- ------------------------------ ------- ---------- ------------ ---------- ---------- ------------------------
------ -----------
TABLE SYS.TEST 147 19 784 SYS CNPEKALT02 sqlplus.exe
6
2jyu

而執行insert append時在表上加的是“6”型別的鎖。

insert append與一般的insert在表上加的鎖不一樣。insert append加的是exclusive的鎖。因此要注意在執行insert append儘快提交,否則會阻塞其它事務對同一張表的DML語句。
此外, ORA-12838:是由於在執行insert append之後沒有提交或回滾,接著又執行DML語句造成的。解決辦法是在insert append 之後加上commit或rollback。
請看下面的測試:
SQL> delete from test;
已刪除9831行。
SQL> insert /*+ append */ into test select * from temp_fsum_od;
已建立3277行。
SQL> insert into test select * from temp_fsum_od;
insert into test select * from temp_fsum_od
*
第 1 行出現錯誤:
ORA-12838: 無法在並行模式下修改之後讀/修改物件

SQL> update test set OD_CODE=upper(OD_CODE) ;
update test set OD_CODE=upper(OD_CODE)
*
第 1 行出現錯誤:
ORA-12838: 無法在並行模式下修改之後讀/修改物件

SQL> delete from test;
delete from test
*
第 1 行出現錯誤:
ORA-12838: 無法在並行模式下修改之後讀/修改物件

SQL>
SQL> insert /*+ append */ into test select * from temp_fsum_od;
insert /*+ append */ into test select * from temp_fsum_od
*
第 1 行出現錯誤:
ORA-12838: 無法在並行模式下修改之後讀/修改物件
注意,我先執行了一個delete語句,又執行了insert append. 這個delete語句並沒有造成後面的insert append報錯。
但在我執行了一個insert append之後,再執行任何DML語句都會報錯。
這說明,在執行了insert append 之後,必須commit或rollback,才能再執行其它DML語句。
但在insert append之前可以執行DML語句,而不會對insert append造成影響。
所以我們注意一點就可以了,即只要業務允許,在執行insert append後馬上提交。