批量插入数据之nologging


Oracle nologging tips

The nologging option is a great way to speed-up inserts and index creation.  It bypasses the writing of the redo log, significantly improving performance.   However, this approach is quite dangerous if you need to roll-forward through this time period during a database recovery. In nologging mode you are running without a safety net when you run nologging operations and you must:

  • Backup before and after - You must take a backup, both before and after all nologging operations

  • Only nologging operations during the nologging window -  Between the backups (the nologging processing window), ONLY nologging operations should be run in the middle of this "backup sandwich".

The nologging clause is quite convoluted and dependent on several factors.

  • Database noarchivelog mode - If your database is in "noarchivelog" mode and you are no using the APPEND hint for inserts, you WILL STILL generate redo logs!

  • Database archivelog mode - If you are in archivelog mode, the table must be altered to nologging mode AND the SQL must be using the APPEND hint.  Else, redo WILL be generated.

You can use nologging for batch  inserts into tables and for creating indexes:

  • You can insert into tables with nologging - If you use the APPEND hint and place the table in nologging mode, redo will be bypassed. 

alter table customer nologging;

insert /*+ append */ into customer values ('hello',';there');

  • You can create indexes with nologging - The only danger with usingnologging is that you must re-run the create index syntax if you perform a roll-forward database recovery.  Using nologging with create index can speed index creation by up to 30%.

create index newidx . . . nologging;

  • Other nologging options - Only the following operations can make use of the NOLOGGING option:
     
        alter table...move partition
        alter table...split partition
        alter index...split partition
        alter index...rebuild
        alter index...rebuild partition
        create table...as select
        create index
        direct load with SQL*Loader
        direct load INSERT (using APPEND)

For more information on using nologging for optimal performance, see my book Oracle Tuning: The Definitive Reference.


Oracle批量插入性能提升方法

1、批量插入—nologging

1.1 nologging 原理


如图,logging是对事务过程的记录,相反的Nologging就是不记录该事务记录,不写入redo文件。

1.2 nologging 作用

批量插入数据,一般人都会想到使用NOLOGING选项,因为他避免了产生大量的日志信息。虽然它能够带来性能上的快速提升,但是对于主要的数据而言,数据备份和恢复确是灾难性的,因此使用的时候需要注意以下几点:

1、打开nologging选项之前备份,以及关闭nologging之后的再次备份(为什么这么提?有其必然的理由,恢复测试看完就明白了)。

2、所有的nologging操作必须在打开和关闭nologging之间操作,否则操作无效。

1.3 nologging 正确使用

如何正确使用nologging呢,以下注意事项:

1、当数据库处于非归档模式的时候,插入大量数据的时候必须使用HINT /*+ APPEND*/ ,否则任然产生REDO信息。

2、当数据库处于归档模式下,首先必须将表置为nologging模式,插入数据也必须使用HINT /*+ APPEND*/ ,否则同样产生日志信息。

 

以上结论可以查看我之前的BLOG的验证NOLOGGING何时生效

1.4 nologging 使用场景

使用 nologging主要场景说明:

1、批量插入:

1 ) 置表为Nologging模式:alter table customer nologging;

2)批量插入语句:insert /*+ append */ into tab;

 

2、创建索引:create index newidx . . . nologging;

 

3、其它使用场景:

alter table...move partition

alter table...split partition

alter index...split partition

alter index...rebuild

alter index...rebuild partition

create table...as select

create index

direct load with SQL*Loader

direct load INSERT (using APPEND)

1.5表nologging/logging模式查看和切换

表是否是logging状态,可以用下列语句查看:

SQL> selecttable_name,logging from dba_tables where table_name=upper('pnologging');

TABLE_NAME                    LOGGING

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

PNOLOGGING                    

 

表nologging/logging模式切换:

SQL> alter table pnologging logging;

Tablealtered

 

那么在Oracle内部还存在一个内部参数:_disable_logging默认是false。通过更改为true可以让Oracle在修改表中的记录的时候完全不记录redo,这个参数要甚用。平时,我们只作为性能测试用。

参数具体参考:http://www.eygle.com/archives/2005/10/oracle_hidden_disable_logging.html

1.6 NOLOGGING对恢复的影响测试(一)

参考:http://space6212.itpub.net/post/12157/509133

Nologging在提高性能的同时,会给恢复带来一定的影响。首先要验证在先发生nologging操作,再备份数据文件的情况下,是否可以完全恢复数据。

1、建分区表PLOGGING和PNOLOGGING

表空间

create tablespace ping datafile '/opt/ora10g/oradata/gis/ping.dbf' size 100m;

 

CREATE TABLE PLOGGING

( A NUMBER,

B NUMBER

)

PARTITION BY LIST (A)

(PARTITION P1 VALUES (1) TABLESPACE PING,

PARTITION P2 VALUES (2) TABLESPACE PING);

 

CREATE TABLE PNOLOGGING

( C NUMBER,

D NUMBER

)

PARTITION BY LIST (C)

(PARTITION P1 VALUES (1) TABLESPACE PING,

PARTITION P2 VALUES (2) TABLESPACE PING);

2、PLOGGING表logging模式插入测试数据

SQL> insertinto plogging select 2,2 from dba_tables WHERE ROWNUM<1000;

999 rows inserted

 

SQL> commit;

Commit complete

 

3、PNOLOGGING表nologging模式插入测试数据

SQL> altertable pnologging nologging;

Table altered

 

SQL> insertinto /*+ Append */ pnologging select 1,1 from dba_tables WHERE ROWNUM<1000;

999 rows inserted

 

SQL> commit;

Commitcomplete

 

SQL> altertable pnologging logging;

Table altered

 

4、确认当期数据量

SQL> selectcount(*) from pnologging;

  COUNT(*)

----------

       999

 

SQL> selectcount(*) from plogging;

  COUNT(*)

----------

       999

5、RMAN备份表空间

RMAN> backup tablespace ping;

Starting backup at 11-FEB-12

using channel ORA_DISK_1

channel ORA_DISK_1: starting full datafilebackupset

channel ORA_DISK_1: specifying datafile(s) inbackupset

input datafile fno=00040 name=/opt/ora10g/oradata/gis/ping.dbf

channel ORA_DISK_1: starting piece 1 at11-FEB-12

channel ORA_DISK_1: finished piece 1 at11-FEB-12

piece handle=/opt/ora10g/product/10.2.0/db_1/dbs/07n32leh_1_1tag=TAG20120211T173929 comment=NONE

channel ORA_DISK_1: backup set complete,elapsed time: 00:00:01

Finished backup at 11-FEB-12

6、PLOGGING和PNOLOGGING表logging模式插入测试数据

SQL> altertable pnologging logging;

Table altered

 

SQL> insertinto pnologging select 1,1 from dba_tables WHERE ROWNUM<501;

500 rows inserted

 

SQL> insertinto plogging select 1,1 from dba_tables WHERE ROWNUM<501;

500 rows inserted

 

SQL> commit;

Commit complete

 

SQL> selectcount(*) from pnologging;

  COUNT(*)

----------

      1499

 

SQL> selectcount(*) from plogging;

  COUNT(*)

----------

      1499

7、模拟损坏表空间数据文件

[oracle@localhost gis]$ echo  /dev/null >  ping.dbf

SQL> Altersystem flush buffer_cache;

System altered

 

SQL> select* from pnologging ;

select * from plogging

ORA-01115: IO error reading block from file 40 (block #780)

ORA-01110: data file 40: '/opt/ora10g/oradata/gis/ping.dbf'

ORA-27091: unable to queue I/O

ORA-27072: File I/O error

Additional information: 4

Additional information: 779

8、恢复数据库

SQL> alter database datafile '/opt/ora10g/oradata/gis/ping.dbf' offline;

Database altered.

 

RMAN> restore tablespace ping;

Starting restore at 11-FEB-12

using target database control file instead ofrecovery catalog

allocated channel: ORA_DISK_1

channel ORA_DISK_1: sid=116 devtype=DISK

 

channel ORA_DISK_1: starting datafilebackupset restore

channel ORA_DISK_1: specifying datafile(s) torestore from backup set

restoring datafile 00040 to /opt/ora10g/oradata/gis/ping.dbf

channel ORA_DISK_1: reading from backup piece/opt/ora10g/product/10.2.0/db_1/dbs/07n32leh_1_1

channel ORA_DISK_1: restored backup piece 1

piece handle=/opt/ora10g/product/10.2.0/db_1/dbs/07n32leh_1_1tag=TAG20120211T173929

channel ORA_DISK_1: restore complete, elapsedtime: 00:00:03

Finished restore at 11-FEB-12

 

RMAN> recover tablespace ping;

Starting recover at 11-FEB-12

using channel ORA_DISK_1

 

starting media recovery

media recovery complete, elapsed time:00:00:02

Finished recover at 11-FEB-12

 

SQL> alter database datafile '/opt/ora10g/oradata/gis/ping.dbf' online;

Database altered.

9、结果

SQL> selectcount(*) from plogging;

  COUNT(*)

----------

      1499

 

SQL> selectcount(*) from pnologging;

  COUNT(*)

----------

      1499

结果的最重要的,看到恢复之后的数据库的数量,和恢复前的一样,说明了做完nologging大数量插入后做备份,之后的操作没有再次进行nologging操作,此次nologging操作的数据是可以被恢复的。

1.7 NOLOGGING对恢复的影响测试(二)

1、建分区表PLOGGING和PNOLOGGING

表空间

create tablespace ping datafile '/opt/ora10g/oradata/gis/ping.dbf' size 100m;

 

CREATE TABLE PLOGGING

( A NUMBER,

B NUMBER

)

PARTITION BY LIST (A)

(PARTITION P1 VALUES (1) TABLESPACE PING,

PARTITION P2 VALUES (2) TABLESPACE PING);

 

CREATE TABLE PNOLOGGING

( C NUMBER,

D NUMBER

)

PARTITION BY LIST (C)

(PARTITION P1 VALUES (1) TABLESPACE PING,

PARTITION P2 VALUES (2) TABLESPACE PING);

2、PLOGGING和PNOLOGGING表logging模式插入测试数据(分区2)

SQL> insertinto plogging select 2,2 from dba_tables WHERE ROWNUM<1000;

999 rows inserted

 

SQL> insertinto pnologging select 2,2 from dba_tables WHERE ROWNUM<1000;

999 rows inserted

 

SQL> commit;

Commit complete

此步操作主要是为了体现表内默认存在的数据量,方便和后面的进行对比。

 

3、确认当期数据量

SQL> selectcount(*) from pnologging;

  COUNT(*)

----------

       999

 

SQL> selectcount(*) from plogging;

  COUNT(*)

----------

       999

4、RMAN备份表空间

RMAN> backup tablespace ping;

Starting backup at 13-FEB-12

using channel ORA_DISK_1

channel ORA_DISK_1: starting full datafilebackupset

channel ORA_DISK_1: specifying datafile(s) inbackupset

input datafile fno=00040 name=/opt/ora10g/oradata/gis/ping.dbf

channel ORA_DISK_1: starting piece 1 at13-FEB-12

channel ORA_DISK_1: finished piece 1 at13-FEB-12

piece handle=/opt/ora10g/product/10.2.0/db_1/dbs/08n37l9v_1_1 tag=TAG20120213T150743comment=NONE

channel ORA_DISK_1: backup set complete,elapsed time: 00:00:01

Finished backup at 13-FEB-12

5、PLOGGING表logging模式插入测试数据(分区1)

SQL> insertinto plogging select 1,1 from dba_tables WHERE ROWNUM<501;

999 rows inserted

6、PNOLOGGING表nologging模式插入测试数据(分区1)

SQL> altertable pnologging nologging;

Table altered

 

SQL> insertinto /*+ Append */ pnologging select 1,1 from dba_tables WHERE ROWNUM<501;

999 rows inserted

 

SQL> commit;

Commitcomplete

 

SQL> altertable pnologging logging;

Table altered

7、确认当期数据量

SQL> selectcount(*) from plogging;

  COUNT(*)

----------

      1499

 

SQL> selectcount(*) from pnologging;

  COUNT(*)

----------

      1499

 

SQL> insertinto plogging select 1,1 from dba_tables WHERE ROWNUM<501;

500 rows inserted

 

SQL> insertinto  pnologging select 1,1 fromdba_tables WHERE ROWNUM<501;

500 rows inserted

 

SQL> commit;

Commit complete

 

SQL> selectcount(*) from plogging;

  COUNT(*)

----------

      1999

 

SQL> selectcount(*) from pnologging;

  COUNT(*)

----------

      1999

8、模拟损坏表空间数据文件

[oracle@localhost gis]$ echo  /dev/null >  ping.dbf

SQL> Altersystem flush buffer_cache;

System altered

 

SQL> select* from pnologging ;

select * from plogging

ORA-01115: IO error reading block from file 40 (block #828)

ORA-01110: data file 40: '/opt/ora10g/oradata/gis/ping.dbf'

ORA-27091: unable to queue I/O

ORA-27072: File I/O error

Additional information: 4

Additional information: 827

9、恢复数据库

SQL> alter database datafile 40 offline;

Database altered.

 

RMAN> restore tablespace ping;

Starting restore at 13-FEB-12

using channel ORA_DISK_1

channel ORA_DISK_1: starting datafilebackupset restore

channel ORA_DISK_1: specifying datafile(s) torestore from backup set

restoring datafile 00040 to /opt/ora10g/oradata/gis/ping.dbf

channel ORA_DISK_1: reading from backup piece/opt/ora10g/product/10.2.0/db_1/dbs/08n37l9v_1_1

channel ORA_DISK_1: restored backup piece 1

piece handle=/opt/ora10g/product/10.2.0/db_1/dbs/08n37l9v_1_1 tag=TAG20120213T150743

channel ORA_DISK_1: restore complete, elapsedtime: 00:00:04

Finished restore at 13-FEB-12

 

RMAN> recover tablespace ping;

 

Starting recover at 13-FEB-12

using channel ORA_DISK_1

starting media recovery

media recovery complete, elapsed time:00:00:02

Finished recover at 13-FEB-12

 

SQL> alter database datafile '/opt/ora10g/oradata/gis/ping.dbf' online;

Database altered.

10、结果

SQL> select count(1) from pnologging;

 

select count(1) from pnologging

ORA-01578: ORACLE 数据块损坏 (文件号 40,块号 3186)

ORA-01110: 数据文件 40: '/opt/ora10g/product/10.2.0/db_1/dbs/07n32leh_1_1'

ORA-26040: 数据块是使用 NOLOGGING 选项加载的

 

SQL> select count(1) from pnologging;

  COUNT(*)

----------

      1999

 

没有发生过nologging操作的表都可以完全恢复,发生过nologging的表的数据不能完全恢复。

 

结论:

如果备份后再发生nologging操作,则

1. 产生nologging操作的表不能被完全恢复。

2. nologging操作只会影响与之发生联系的表,不会影响其他表。

3. 如果表是非分区表,则会影响全表。如果nologging影响的表是分区表,nologging操作只会影响受该操作影响的数据对应的分区,而不影响其他分区。

例如T有两个分区P1和P2,在备份后对T发生了nologging操作,但只影响了P1的数据,则恢复时,可以正常访问P2的数据,而访问P1时会报错。

4. 即使nologging操作后的操作都是logging方式,也不能恢复后面的数据 。

5. nologging虽然可以提高性能,但是可能会造成数据无法恢复,因此使用这一特性时要非常谨慎。

一般在如下情况下才建议使用:(或者Nologging前要备份,nologging后也要立刻备份)

1) 临时表

2) 中间表

3) 数据可轻易重新生成的表

4) 创建索引

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle中,大量插入数据时,可以采用以下优化方法: 1. 使用批量插入语句 使用批量插入语句可以大大提高插入数据的效率。在Oracle中,可以使用INSERT ALL语法或者使用INSERT INTO SELECT语法来实现批量插入。 示例: ``` -- 使用INSERT ALL语法 INSERT ALL INTO employees (employee_id, first_name, last_name) VALUES (1001, 'John', 'Doe') INTO employees (employee_id, first_name, last_name) VALUES (1002, 'Jane', 'Doe') INTO employees (employee_id, first_name, last_name) VALUES (1003, 'Bob', 'Smith') SELECT 1 FROM DUAL; -- 使用INSERT INTO SELECT语法 INSERT INTO employees (employee_id, first_name, last_name) SELECT 1001, 'John', 'Doe' FROM DUAL UNION ALL SELECT 1002, 'Jane', 'Doe' FROM DUAL UNION ALL SELECT 1003, 'Bob', 'Smith' FROM DUAL; ``` 2. 禁用日志记录 如果对数据的完整性和恢复性没有严格的要求,可以考虑禁用日志记录。在插入数据时,使用NOLOGGING选项可以减少写入日志的数量,提高插入数据的速度。需要注意的是,禁用日志记录可能会导致数据丢失或者不一致,需要谨慎使用。 示例: ``` INSERT /*+ APPEND NOLOGGING */ INTO employees (employee_id, first_name, last_name) VALUES (1001, 'John', 'Doe'); ``` 3. 使用并行插入 在Oracle中,可以使用并行插入来提高插入数据的速度。在执行插入语句时,使用PARALLEL选项可以让Oracle使用多个进程并行插入数据。需要注意的是,并行插入需要在数据库中配置好并行环境,否则可能会导致性能下降。 示例: ``` INSERT /*+ PARALLEL(employees, 4) */ INTO employees (employee_id, first_name, last_name) VALUES (1001, 'John', 'Doe'); ``` 以上是Oracle中大量插入数据的几种优化方法,需要根据具体情况选择合适的方法来提高插入数据的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值