insert中启用错误日志的问题及分析

在平时的工作中,有时候需要insert一批数据,这些数据可能是临时表,外部表,普通表,子查询等形式,类似下面的格式
insert into xxxx (select xxxxx from xxx where xxxxx);
如果其中有冗余数据的时候,整个Insert会自动rollback,一条数据也插不进去,错误类似下面的形式。
insert /*+ append */into mo1_memo select *from MO1_MEMO_EXT_92;
*
ERROR at line 1:
ORA-00001: unique constraint (MIG_TEST.MO1_MEMO_PK) violated

可能我们想保证正常数据能够插入,对于违反约束等的数据稍后处理,这个是用错误日志就是一个很好的选择。
首先就是创建错误日志,可以使用提供的包来创建,也可以手动创建。
这里我需要用到表含有lob字段,创建错误日志的时候有下面的错误。
EXEC DBMS_ERRLOG.create_error_log(dml_table_name => 'MO1_MEMO')
BEGIN DBMS_ERRLOG.create_error_log(dml_table_name => 'MO1_MEMO'); END;


ERROR at line 1:
ORA-20069: Unsupported column type(s) found: MEMO_SYSTEM_TEXT_C
ORA-06512: at "SYS.DBMS_ERRLOG", line 235
ORA-06512: at line 1

不过想想也是合理的。不过问题还是要解决的。
可以看看创建错误日志的包,oracle已经考虑到了,我们可以忽略这种不支持的类型,当然还可以指定错误日志的名字。
SQL> desc dbms_errlog
PROCEDURE CREATE_ERROR_LOG
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 DML_TABLE_NAME                 VARCHAR2                IN
 ERR_LOG_TABLE_NAME             VARCHAR2                IN     DEFAULT
 ERR_LOG_TABLE_OWNER            VARCHAR2                IN     DEFAULT
 ERR_LOG_TABLE_SPACE            VARCHAR2                IN     DEFAULT
 SKIP_UNSUPPORTED               BOOLEAN                 IN     DEFAULT


我们创建错误日志
SQL> EXEC DBMS_ERRLOG.create_error_log(dml_table_name => 'MO1_MEMO',SKIP_UNSUPPORTED=>true,ERR_LOG_TABLE_NAME=>'MO1_MEMO_ERROR');
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.03

尝试插入有冗余的数据,
SQL> insert /*+ append  */into mo1_memo select *from MO1_MEMO_EXT_92 LOG ERRORS INTO MO1_MEMO_ERROR('test_unique') REJECT LIMIT UNLIMITED
  2  /
insert /*+ append */into mo1_memo select *from MO1_MEMO_EXT_92 LOG ERRORS INTO MO1_MEMO_ERROR('test_unique') REJECT LIMIT UNLIMITED
*
ERROR at line 1:
ORA-00001: unique constraint (MIG_TEST.MO1_MEMO_PK) violated
Elapsed: 00:00:17.32

直接抛了错误,看来错误日志没有正确启用。
查看错误日志,里面也是空的。
SQL> SELECT *FROM MO1_MEMO_ERROR;  --no rows

反复尝试,最后发现是Hint的原因,去掉Hint 就没有问题了。
SQL> insert into mo1_memo select *from MO1_MEMO_EXT_92 LOG ERRORS INTO MO1_MEMO_ERROR('test_unique') REJECT LIMIT UNLIMITED;
99 rows created.
Elapsed: 00:04:04.83

  1* select count(*)from mo1_memo_error
SQL> /
  COUNT(*)
----------
    907544

错误日志里面有详细的数据信息。但是如果足够细心查看执行时间的话,就会发现如果不使用append,性能就会差很多。
下面是一个简单的测试,
如果不使用append的时候,插入80万左右的数据在1分钟左右,如果使用了append就只需要大概13秒左右。
还有上面的测试结果,如果80万记录中99%左右的数据有冗余,插入错误日志就需要大概4分钟的样子
SQL> insert into mo1_memo select * from mo1_memo_ext_99 LOG ERRORS INTO MO1_MEMO_ERROR REJECT LIMIT UNLIMITED;
877245 rows created.
Elapsed: 00:01:12.91

SQL> insert into mo1_memo select * from mo1_memo_ext_98;
753637 rows created.
Elapsed: 00:01:04.75

SQL> rollback;
Rollback complete.
Elapsed: 00:00:56.35

SQL> insert /*+append*/ into mo1_memo select *from mo1_memo_ext_98;
753637 rows created.
Elapsed: 00:00:13.20

所以启用错误日志可以根据大家的需求来选择,有利有弊。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23718752/viewspace-1190545/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/23718752/viewspace-1190545/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值