用sql loader时若有唯一索引需慎用direct方式

以前一直没注意sql loader用direct方式时怎么处理索引的,也是因为一般用sql loader都是往临时表里导数据,用不着索引。今天试了一下,才发现direct=true时索引不是在insert时维护的,而是在把数据全部插入后再去维护。

以下是实验

 

设 SQLLDR表上字段 ID建立了PK PK_SQLLDR,相应的索引为UK_SQLLDR

表中已经有了一条ID=0的记录,sqlldr的ctl文件采用append方式

===================================================

不采用direct方式时>sqlldr aeowner/aeowner@jinlo control=sqlldr.1.ctl

log中显示这条记录没有被插入

记录 1: 被拒绝 - 表 SQLLDR 出现错误。
ORA-00001: 违反唯一约束条件 (AEOWNER.PK_SQLLDR)

看一下,确实没有插入

select count(0) from SQLLDR where id=0;
 
  COUNT(0)
----------
         1

 

=====================================================

采用direct方式时>sqlldr aeowner/aeowner@jinlo control=sqlldr.1.ctl direct=true

log中没有异常记录

这条记录确实被插入了

SQL> select count(0) from SQLLDR where id=0;
 
  COUNT(0)
----------
         2

 

相应的索引也处于不可用状态

SQL> select status from dba_indexes where table_name='SQLLDR' and index_name='PK_SQLLDR';
 
STATUS
--------
UNUSABLE

 

并且,由于建立了主键,整个表上的写操作都无法进行

 

SQL> delete from sqlldr where id=0;
 
delete from sqlldr where id=0
 
ORA-01502: 索引 'AEOWNER.PK_SQLLDR' 或这类索引的分区处于不可用状态

 

insert into sqlldr (id) values (1);
 
insert into sqlldr (id) values (1)
 
ORA-01502: 索引 'AEOWNER.PK_SQLLDR' 或这类索引的分区处于不可用状态

=====================================================

 

以上实验可知,对于目标表上有约束(唯一索引)的情况,direct方式可能会破坏数据的完整性,甚至使得后续操作无法继续进行。因此

1) 不是出于性能考虑的话,不要采用direct方式

2) 如果采用direct方式,检查结果时,不能只看sqlldr的log中,还要检查目标表上唯一索引的status,以防悄悄地引入错误数据

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值