用直接路徑(direct-path)insert提高性能的兩種方法

一、傳統串行insert方式

常見的insert方式有兩種:html

(1) insert into table_name values(....)數據庫

(2) insert into target_table select* from source_tablesession

上面這兩種常規的插入式,默認都是在串行方式下的插入,會將insert的數據寫入buffer_cache,插入前檢查表中是否有block中存有空閒空間能夠追加插入,並寫入redo log。app

二、直接路徑(direct-path)insert優勢與使用要點

2.一、Direct-path insert 方式的優勢

(1) 能夠將insert數據跳過buffer_cahce,省掉了buffer block的格式化與DBWR操做,直接從PGA寫入磁盤less

(2) 不檢查表中現有的block是否有空閒空間,直接在表的高水位線(HWM)以上插入性能

(3) 若是在數據庫處於非歸檔模式下,或者是數據就處於歸檔模式,表級處於nologging狀態下,只有少許的空間信息redo寫入、不寫入數據undo(由於要回滾時能夠直接回退到高水線便可,而不須要針對insert生成delete的回滾記錄),因此在特定的狀況下,直接路徑(direct-path)的insert方式,在性能上遠遠快於常規的串行插入方式。ui

2.二、使用direct-path insert須要特別注意的要點

2.2.1 DB非force loggging模式下direct-path insert對redo與undo的寫入影響

若是在數據庫處於歸檔模式,以及表處於logging模式下,直接路徑(direct-path)性能提高會大打折扣,由於,雖然direct-path能生效,可是仍然會記錄下完整的redo和undo。spa

也就是說,在歸檔模式下,還須要將表改爲nologging模式,纔不會寫數據的redo。日誌

2.2.2 DB force logging模式下direct-pathinsert對redo的寫入影響

Note: If the database or tablespace is in FORCE LOGGING mode, thenorm

direct-path INSERT always logs, regardless of the logging setting.

若是數據庫或表空間在forcelogging模式,則direct-path insert老是會寫日誌,不管logging如何設置。

三、使用直接路徑(direct-path)insert的方法

3.1 方法一:使用/*+ APPEND */ hint方式

如下爲ORACLE官方技術資料對APPENDhint的說明:

APPEND hint: Instructs the optimizer to use direct-path INSERT (data is appended to the

end of the table, regardless of whether there is free space in blocks below the high

watermark)

3.1.1 數據庫非歸檔模式下使用/*+ APPEND*/ hint方式

當數據庫處於非歸檔模式下,無論表爲logging模式仍是nologging模式,使用/*+APPEND */ hint,既可使用direct-path,還將不記錄redo和undo

 

用法以下:

INSERT /*+ APPEND */ INTO new_object SELECT * FROM dba_objects;

3.1.2 數據庫處於歸模模式下使用/*+APPEND */ hint方式

當數據庫處於歸模模式下,若表爲logging模式,即使使用/*+APPEND */ hint,雖然direct-path能夠起到做用,可是insert操做仍然會寫redo記錄,就算你在insert語句上加nologging也不會有效果,redo日誌與undo照寫不誤。

須要通修改表或修改索引,或修改表空間的no-logging模式來達到不寫redo與undo的效果

如下爲從metalink(文檔ID166727.1)中找到的技術資料:

The APPEND hint is required for using serial direct-load INSERT.

Direct-load INSERT operations can be done without logging of redo

information in case the database is in ARCHIVELOG mode.

Redo information generation is suppressed by setting no-logging

mode for the table, partition, or index into which data will be

inserted by using an ALTER TABLE, ALTER INDEX, or ALTER TABLESPACE

command.

用法以下:

Alter table new_object nologging;

INSERT /*+ APPEND */ INTO new_object SELECT * FROM dba_objects;

 

3.2 方法二:DML並行模式的方式

DML並行模式下,direct-path插入方式是默認的,固然,在DML並行模式下若是想不使用direct-path插入,能夠經過加noappendhint實現。如下是DML並行模式下的direct-path插入:

並行DML的前提條件:

(1)ORACLE版本爲Oracle Enterprise Edition

(2)操做的會話開啓並行DML

(3)下面三項要求必須知足一項:

1)目標表上開啓並行屬性(DEGREE)

2)插入語句中指定並行提示(/*+ parallel n */)

3)有設置PARALLEL_DEGREE_POLICY參數的值爲AUTO

以數據庫爲非歸檔模式用法爲例(注意歸檔模式,還需將表改爲nologging模式):

(1)alter session enable parallel dml;

語句還有選項有::ALTER SESSION { ENABLE | FORCE } PARALLEL DML;

(2)alter table new_object_directpath parallel 8;

(3)insert /*+PARALLEL(new_object_directpath, 8) */into new_object_directpathnologging select * from new_object_old;

 

四、歸檔模式下傳統串行方式與direct-path方式insert性能對比

環境說明:

源表名

test_dba_objects

源錶行數

1630104

源表segment大小

184MB

操做步驟與性能對比結果以下:

傳統串行insert方式

APPEND hint的direct-path insert方式

DML並行的direct-path insert方式

(1)建表與修改設定

SQL>create table new_object_directpath as select * from test_dba_objects where 1=2

 

SQL>alter table new_object_directpath nologging

SQL> SET TIMING ON

Elapsed: 00:00:00.54

 

(2)insert耗時

SQL> insert into new_object_directpathnologgingselect * from test_dba_objects;

 

1630104 rows created.

 

 

Elapsed: 00:00:12.43

未產生數據redo與undo

(1)建表與修改設定

SQL>create table new_object_directpath as select * from test_dba_objects where 1=2

 

SQL>alter table new_object_directpath nologging

SQL> SET TIMING ON

Elapsed: 00:00:00.54

 

(2)insert耗時

SQL> insert /*+APPEND */into new_object_directpath select * from test_dba_objects;

 

1630104 rows created.

 

 

Elapsed: 00:00:05.83

未產生數據redo與undo

SQL>create table new_object_directpath as select * from test_dba_objects where 1=2

 

SQL>alter table new_object_directpath nologging

SQL> SET TIMING ON

Elapsed: 00:00:00.54

 

(2)修改表的並行模式

SQL> alter table new_object_directpath parallel 8;

 

(3) insert耗時

SQL> insert /*+parallel (new_object_directpath,8) */ into new_object_directpath select * from test_dba_objects;

 

1630104 rows created.

 

Elapsed: 00:00:05.61

未產生數據redo與undo

http://www.2cto.com/database/201501/369138.html

相關文章
相關標籤/搜索