一 非歸檔模式下
D:>sqlplus "/ as sysdba"
數(shù)據(jù)庫版本為9.2.0.1.0
SQL*Plus: Release 9.2.0.1.0 - Production on 星期一 8月 14 10:20:39 2006
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
連接到:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production
當(dāng)前session產(chǎn)生的redo
SQL> create or replace view redo_size
2 as
3 select value
4 from v$mystat, v$statname
5 where v$mystat.statistic# = v$statname.statistic#
6 and v$statname.name = 'redo size';
視圖已建立。
授權(quán)給相應(yīng)數(shù)據(jù)庫schema
SQL> grant select on redo_size to liyong;
授權(quán)成功。
SQL> shutdown immediate;
數(shù)據(jù)庫已經(jīng)關(guān)閉。
已經(jīng)卸載數(shù)據(jù)庫。
ORACLE 例程已經(jīng)關(guān)閉。
SQL> startup mount;
ORACLE 例程已經(jīng)啟動(dòng)。
Total System Global Area 122755896 bytes
Fixed Size 453432 bytes
Variable Size 88080384 bytes
Database Buffers 33554432 bytes
Redo Buffers 667648 bytes
數(shù)據(jù)庫裝載完畢。
非歸檔模式
SQL> alter database noarchivelog;
數(shù)據(jù)庫已更改。
SQL> alter database open;
數(shù)據(jù)庫已更改。
SQL> create table redo_test as
2 select * from all_objects where 1=2;
表已創(chuàng)建。
SQL> select * from sys.redo_size;
VALUE
----------
59488
SQL> insert into redo_test
2 select * from all_objects;
已創(chuàng)建28260行。
SQL> select * from sys.redo_size;
VALUE
----------
3446080
SQL> insert /*+ append */ into redo_test
2 select * from all_objects;
已創(chuàng)建28260行。
SQL> commit;
提交完成。
SQL> select * from sys.redo_size;
VALUE
----------
3458156
可以看到insert /*+ append */ into方式redo產(chǎn)生很少.
SQL> select 3446080-59488,3458156-3446080 from dual;
3446080-59488 3458156-3446080
------------- ---------------
3386592 12076
將表redo_test置為nologging狀態(tài).
SQL> alter table redo_test nologging;
表已更改。
SQL> select * from sys.redo_size;
VALUE
----------
3460052
SQL> insert into redo_test
2 select * from all_objects;
已創(chuàng)建28260行。
SQL> commit;
提交完成。
SQL> select * from sys.redo_size;
VALUE
----------
6805876
SQL> insert /*+ append */ into redo_test
2 select * from all_objects;
已創(chuàng)建28260行。
SQL> commit;
提交完成。
SQL> select * from sys.redo_size;
VALUE
----------
6818144
非歸檔模式下表的nologging狀態(tài)對(duì)于redo影響不大
SQL> select 6805876-3460052,6818144-6805876 from dual;
6805876-3460052 6818144-6805876
--------------- ---------------
3345824 12268
結(jié)論: 在非歸檔模式下通過insert /*+ append */ into方式批量加載數(shù)據(jù)可以大大減少redo產(chǎn)生.
二 歸檔模式下
SQL> shutdown immediate;
數(shù)據(jù)庫已經(jīng)關(guān)閉。
已經(jīng)卸載數(shù)據(jù)庫。
ORACLE 例程已經(jīng)關(guān)閉。
SQL> startup mount;
ORACLE 例程已經(jīng)啟動(dòng)。
Total System Global Area 122755896 bytes
Fixed Size 453432 bytes
Variable Size 88080384 bytes
Database Buffers 33554432 bytes
Redo Buffers 667648 bytes
數(shù)據(jù)庫裝載完畢。
SQL> alter database archivelog;
數(shù)據(jù)庫已更改。
SQL> alter database open;
數(shù)據(jù)庫已更改。
SQL> conn liyong
請(qǐng)輸入口令:
已連接。
將表redo_test重新置為logging
SQL> alter table redo_test logging;
表已更改。
SQL> select * from sys.redo_size;
VALUE
----------
5172
SQL> insert into redo_test
2 select * from all_objects;
已創(chuàng)建28260行。
SQL> commit;
提交完成。
SQL> select * from sys.redo_size;
VALUE
----------
3351344
SQL> insert /*+ append */ into redo_test
2 select * from all_objects;
已創(chuàng)建28260行。
SQL> commit;
提交完成。
SQL> select * from sys.redo_size;
VALUE
----------
6659932
可以看到在歸檔模式下,且表的logging屬性為true,insert /*+ append */ into這種方式也會(huì)紀(jì)錄大量redo
SQL> select 3351344-5172,6659932-3351344 from dual;
3351344-5172 6659932-3351344
------------ ---------------
3346172 3308588
將表置為nologging
SQL> alter table redo_test nologging;
表已更改。
SQL> select * from sys.redo_size;
VALUE
----------
6661820
SQL> insert into redo_test
2 select * from all_objects;
已創(chuàng)建28260行。
SQL> commit;
提交完成。
SQL> select * from sys.redo_size;
VALUE
----------
10008060
SQL> insert /*+ append */ into redo_test
2 select * from all_objects;
已創(chuàng)建28260行。
SQL> commit;
提交完成。
SQL> select * from sys.redo_size;
VALUE
----------
10022852
可以發(fā)現(xiàn)在歸檔模式,要設(shè)置表的logging屬性為false,才能通過insert /*+ append */ into大大減少redo產(chǎn)生.
SQL> select 10008060-6661820,10022852-10008060 from dual;
10008060-6661820 10022852-10008060
---------------- -----------------
3346240 14792
結(jié)論: 在歸檔模式下,要設(shè)置表的logging屬性為false,
才能通過insert /*+ append */ into大大減少redo.
三 下面我們?cè)倏匆幌略跉w檔模式下,幾種批量insert操作的效率對(duì)比.
redo_test表有45W條記錄
SQL> select count(*) from redo_test;
COUNT(*)
----------
452160
1 最常見的批量數(shù)據(jù)加載 25秒
SQL> create table insert_normal as
2 select * from redo_test where 0=2;
表已創(chuàng)建。
SQL> set timing on
SQL> insert into insert_normal
2 select * from redo_test;
已創(chuàng)建452160行。
提交完成。
已用時(shí)間: 00: 00: 25.00
2 使用insert /*+ append */ into方式(這個(gè)的原理可以參見<<批量DML操作優(yōu)化建議.txt>>),但紀(jì)錄redo. 17.07秒
SQL> create table insert_hwt
2 as
3 select * from redo_test where 0=2;
表已創(chuàng)建。
SQL> insert /*+ append */ into insert_hwt
2 select * from redo_test;
已創(chuàng)建452160行。
提交完成。
已用時(shí)間: 00: 00: 17.07
3 使用insert /*+ append */ into方式,且通過設(shè)置表nologging不紀(jì)錄redo.
SQL> create table insert_hwt_with_nologging nologging
2 as
3 select * from redo_test where 2=0;
表已創(chuàng)建。
/*
或者通過
alter table table_name nologging設(shè)置
*/
SQL> insert /*+ append */ into insert_hwt_with_nologging 11.03秒
2 select * from redo_test;
已創(chuàng)建452160行。
提交完成。
已用時(shí)間: 00: 00: 11.03
總結(jié):
我們看到對(duì)于批量操作,如果設(shè)置表nologging,可以大大提高性能.原因就是Oracle沒有紀(jì)錄DML所產(chǎn)生的redo.
當(dāng)然,這樣會(huì)影響到備份。nologging加載數(shù)據(jù)后要做數(shù)據(jù)庫全備.