oracle nologging和append

47328983發表於2012-05-23
前段時間,做一些SQLLDR的資料導進資料庫,思考了一下,如何能把匯入速度提高一下。所以就GOOGLE了一下。找到了一些NOLOGGING和APPEND的相關資料,在此記錄一下。

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

有許多朋友誤已寫SQL或把表的屬性加NOLOGGING,就可以不採成日誌。這是一個誤解。

在資料遷移或大量的資料insert入庫時,由於大量資料的insert或修改,經常引起redo log sync的等待,造成資料庫效能緩慢。
因為許多朋友對NOLOGGING的誤解,所以許多人在insert資料時,在SQL後加nologging,想通過該用法使操作不採生日記錄。但無效果。
這裡討論nologging的具體用法:

資料庫操作,只有如下幾種情況下不產成redo記錄:
1、用sql*load的direct load方式時,不採用redo記錄
2、用insert的direct方式,即在append方式insert
3、create table .... as select
4、create index
5、alter table ... move partition
6、alter table ... split partition
7、alter index ... split partition
8、alter index ... rebuild
9、alter index ... rebuild partition
10、INSERT, UPDATE, and DELETE on LOBs in NOCACHE NOLOGGING mode stored out of line

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

可以採用NOLOGGING模式執行以下操作: 
1 索引的建立和ALTER(重建)。 
2 表的批量INSERT(通過/*+APPEND */提示使用“直接路徑插入“。或採用SQL*Loader直接路徑載入)。表資料不生成redo,但是 
所有索引修改會生成redo,但是所有索引修改會生成redo(儘管表不生成日誌,但這個表上的索引卻會生成redo!)。 
3 LOB操作(對大物件的更新不必生成日誌)。 
4 通過CREATE TABLE AS SELECT建立表。 
5 各種ALTER TABLE操作,如MOVE和SPLIT。 
在一個ARCHIVELOG模式的資料庫上,如果NOLOGGING使用得當,可以加快許多操作的速度,因為它能顯著減少生成的重做日 
志量。假設你有一個表,需要從一個表空間移到另一個表空間。可以適當地排程這個操作,讓它在備份之後緊接著發生,這樣就能把表 
ALTER為NOLOGGING模式,移到表,建立索引(也不生成日誌),然後再把表ALTER回LOGGING模式。現在,原先需要X小時才能 
完成的操作可能只需要X/2 小時(執行是會不會真的減少50%的時間,這一點我不敢打保票!)。要想適當地使用這個特性,需要DBA的 
參與,或者必須與負責資料庫備份和恢復(或任何備用資料庫)的人溝通。如果這個人不知道使用了這個特性,一旦出現介質失敗,就可 
能丟失資料,或者備用資料庫的完整性可能遭到破壞。對此一定要三思。 
使用範例 
create table t 
NOLOGGING 
as 
select * from all_objects 
關於NOLOGGING操作,需要注意以下幾點: 
1 事實上,還是會生成一定數量的redo。這些redo的作用是保護資料字典。這是不可避免的。與以前(不使用NOLOGGING)相 
比,儘管生成的redo量要少多了,但是確實會有一些redo。 
2 NOLOGGING不能避免所有後續操作生成redo。在前面的例子中,我建立的並非不生成日誌的表。只是建立表(CREATE TABLE) 
這一個操作沒有生成日誌。所有後續的“正常“操作(如INSERT、UPDATE和DELETE)還是會生成日誌。其他特殊的操作(如 
使用SQL*Loader的直接路徑載入,或使用INSERT /*+ APPEND */語法的直接路徑插入)不生成日誌(除非你ALTER這個表, 
再次啟用完全的日誌模式)。不過,一般來說,應用對這個表執行的操作都會生成日誌。 
3 在一個ARCHIVELOG 模式的資料庫上執行NOLOGGING 操作後,必須儘快為受影響的資料檔案建立一個新的基準備份,從而 
避免由於介質失敗而丟失對這些物件的後續修改。實際上,我們並不會丟失後來做出的修改,因為這些修改確實在重做日誌中; 
我們真正丟失的只是要應用這些修改的資料(即最初的資料)。

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

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對同一個表並行載入資料,並不一定會提高速度。因為每一時刻只能有一個程式在載入(排它鎖造成)。

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

相關文章