前言
前段時間報表數據庫上有條insert sql語句,插入的大量數據,執行非常慢,需要對其進行分析優化。
分析步驟是在:ARCHIVE與NOARCHIVE模式下進行。
測試場景: 分別對表的常規插入,表在append插入,表在append + parallel插入進行性能測試,得出結果。
環境准備
| 數據庫版本 | 基礎表 | nologging表 | logging表 |
|---|---|---|---|
| Oracle 11g | T1 | T2 | T3 |
#創建T1,T2,T3表
create table t1 as select * from dba_objects;
create table t2 as select * from dba_objects where 1=2;
create table t3 as select * from dba_objects where 1=2;
#往T1表插入數據
SQL> insert into t1 select * from t1;
72813 rows created.
SQL> /
145626 rows created.
SQL> /
291252 rows created.
SQL> select count(*) from t1; COUNT(*)
----------
582504
#設置T2表為nologging屬性
SQL> alter table t2 nologging;
Table altered.
數據庫處於ARCHIVE時
常規插入
nologging 表T2
SQL> insert into t2 select * from t1;
commit;
582824 rows created.
Execution Plan ----------------------------------------------------------
Plan hash value: 3617692013
--------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 582K| 53M| 1455 (2)| 00:00:18 |
| 1 | LOAD TABLE CONVENTIONAL | T2 | | | | |
| 2 | TABLE ACCESS FULL | T1 | 582K| 53M| 1455 (2)| 00:00:18 | ---------------------------------------------------------------------------------
Statistics ----------------------------------------------------------
3345 recursive calls
46879 db block gets
27878 consistent gets
8269 physical reads
67752144 redo size
838 bytes sent via SQL*Net to client
784 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
582824 rows processed
SQL>
Commit complete.
耗費:67752144 redo size
logging 表T3
SQL> insert into t3 select * from t1;
commit;
582824 rows created.
Execution Plan ----------------------------------------------------------
Plan hash value: 3617692013
--------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 582K| 53M| 1455 (2)| 00:00:18 |
| 1 | LOAD TABLE CONVENTIONAL | T3 | | | | |
| 2 | TABLE ACCESS FULL | T1 | 582K| 53M| 1455 (2)| 00:00:18 | ---------------------------------------------------------------------------------
Statistics ----------------------------------------------------------
2860 recursive calls
46875 db block gets
27811 consistent gets
1 physical reads
67875992 redo size
829 bytes sent via SQL*Net to client
784 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
SQL>
Commit complete.
耗費:67875992 redo size
append 插入
nologging 表T2
SQL> insert /*+ append */ into t2 select * from t1;
commit;
582824 rows created.
Execution Plan ----------------------------------------------------------
ERROR:
ORA-12838: cannot read/modify an object after modifying it in parallel
SP2-0612: Error generating AUTOTRACE EXPLAIN report
Statistics ----------------------------------------------------------
2627 recursive calls
9324 db block gets
8832 consistent gets
0 physical reads
143436 redo size
824 bytes sent via SQL*Net to client
798 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:143436 redo size
logging 表T3
SQL> insert /*+ append */ into t3 select * from t1;
582824 rows created.
Execution Plan ----------------------------------------------------------
ERROR:
ORA-12838: cannot read/modify an object after modifying it in parallel
SP2-0612: Error generating AUTOTRACE EXPLAIN report
Statistics ----------------------------------------------------------
2627 recursive calls
9327 db block gets
8832 consistent gets
0 physical reads
68384900 redo size
822 bytes sent via SQL*Net to client
797 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:68384900 redo size
parallel + append 插入
nologging 表T2
SQL> alter session enable parallel dml;
insert /*+ append parallel(2) */ into t2 select * from t1;
commit;
Session altered.
SQL>
582824 rows created.
Execution Plan ----------------------------------------------------------
ERROR:
ORA-12838: cannot read/modify an object after modifying it in parallel
SP2-0612: Error generating AUTOTRACE EXPLAIN report
Statistics ----------------------------------------------------------
52 recursive calls
32 db block gets
19 consistent gets
0 physical reads
21916 redo size
824 bytes sent via SQL*Net to client
809 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:21916 redo size
logging 表T3
SQL> alter session enable parallel dml;
insert /*+ append parallel(2)*/ into t3 select * from t1;
commit;
Session altered.
SQL>
582824 rows created.
Execution Plan ----------------------------------------------------------
ERROR:
ORA-12838: cannot read/modify an object after modifying it in parallel
SP2-0612: Error generating AUTOTRACE EXPLAIN report
Statistics ----------------------------------------------------------
50 recursive calls
33 db block gets
20 consistent gets
0 physical reads
21308 redo size
824 bytes sent via SQL*Net to client
808 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:21308 redo size
數據庫處於NOARCHIVE時
常規插入
nologging 表T2
Execution Plan ----------------------------------------------------------
Plan hash value: 3617692013
--------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 582K| 53M| 1455 (2)| 00:00:18 |
| 1 | LOAD TABLE CONVENTIONAL | T2 | | | | |
| 2 | TABLE ACCESS FULL | T1 | 582K| 53M| 1455 (2)| 00:00:18 | ---------------------------------------------------------------------------------
Statistics ----------------------------------------------------------
2538 recursive calls
46869 db block gets
27796 consistent gets
8266 physical reads
67754744 redo size
824 bytes sent via SQL*Net to client
784 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:67754744 redo size
logging 表T3
Execution Plan ----------------------------------------------------------
Plan hash value: 3617692013
--------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 582K| 53M| 1455 (2)| 00:00:18 |
| 1 | LOAD TABLE CONVENTIONAL | T3 | | | | |
| 2 | TABLE ACCESS FULL | T1 | 582K| 53M| 1455 (2)| 00:00:18 | ---------------------------------------------------------------------------------
Statistics ----------------------------------------------------------
2593 recursive calls
46873 db block gets
27800 consistent gets
1600 physical reads
67757328 redo size
824 bytes sent via SQL*Net to client
784 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:67757328 redo size
append 插入
nologging 表T2
Statistics ----------------------------------------------------------
2627 recursive calls
9324 db block gets
8832 consistent gets
2993 physical reads
143480 redo size
822 bytes sent via SQL*Net to client
798 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:143480 redo size
logging 表T3
Statistics ----------------------------------------------------------
2627 recursive calls
9327 db block gets
8832 consistent gets
0 physical reads
143420 redo size
821 bytes sent via SQL*Net to client
798 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:143420 redo size
parallel + append 插入
nologging 表T2
Statistics ----------------------------------------------------------
50 recursive calls
32 db block gets
21 consistent gets
0 physical reads
21896 redo size
823 bytes sent via SQL*Net to client
810 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:21896 redo size
logging 表T3
Statistics ----------------------------------------------------------
50 recursive calls
33 db block gets
20 consistent gets
0 physical reads
21896 redo size
821 bytes sent via SQL*Net to client
809 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
582824 rows processed
耗費:21896 redo size
綜合比較
| 屬性 | 表名 | 常規插入產生的redo size | apppend插入產生的redo size | apppend + parallel插入產生的redo size |
|---|---|---|---|---|
| 數據庫模式 | archive | |||
| nologing | t2 | 67752144 | 143436 | 21916 |
| loging | t3 | 67875992 | 68384900 | 21308 |
| 數據庫模式 | noarchive | |||
| nologing | t2 | 67754744 | 143480 | 21896 |
| loging | t3 | 67757328 | 143420 | 21896 |
1)數據庫處於ARCHIVE模式時,
對logging表執行append插入,是對性能沒有優化的。加並行parallel才會有影響。
2)數據庫處於NOARCHIVE模式時,對logging表執行append插入,可以有效的提升性能。當然加並行parallel效果會更好
