客户的一张表中出现重复数据,而该列由唯一键约束,重复值如何产生的呢?

简介: 批量加载数据时要小心,唯一键、索引可能会失效

oraclebulkcopy:https://docs.oracle.com/html/E10927_01/OracleBulkCopyClass.htm#CHDHHABB

1、问题

客户的一张表中出现重复数据,而该列由唯一键约束,重复值如何产生的呢?
事情的起因是客户遇到ORA-02291外键问题,外键更新列没有找到主表中的列值,由业务去排查,但是通过这个问题进一步发现了业务的重复数据的潜在问题,
及时调整避免长期运行造成更大的问题。
报错如下:
ORA-02291: integrity constraint (ERP_CC.T_ECHDA_T_EZBQGDA_FK1) violated - parent key not found
ORA-06512: at "ERP_CC.UPDATET_ECHDABYT_TMH_PROC", line 346
ORA-06512: at line 1
检查该表的DDL,截取问题部分如下,发现唯一键unusable,一个外键disable,但不是ORA-02291对应的外键,
1

进一步排查,发现唯一键YBH28 包含3307条重复数据,这是怎么产生的呢?唯一索引状态还是unusable的。

2、排查

从客户近期的业务调整得知,业务新改动了加载数据的方法,使用了oraclebulkcopy的方式加载数据,insert语句出现 /+ SYS_DL_CURSOR / hint,
该hint就是SQL Loader的方式, 相当于sqlldr(direct=true)直接路径加载,会导致索引失效,因此Bulkcopy需要谨慎使用,要性能的时候要考虑重复数据如何避免。
2

3、解决

问题根源找到了,修改加载数据的方法,同时业务去处理重复数据,重新加一下唯一键,失效的外键启用,外键插入引起的ORA-02291问题业务上去检查避免。

4、总结

oraclebulkcopy对应的实现是sqlloader加载数据,有如下限制:
1、会disbale索引
2、direct=true模式加载数据,表的约束会在过程中失效
3、对表加排它锁。

SQL*Loader leaves indexes in an Index Unusable state when the data segment being loaded becomes more up-to-date than the index segments that index it.
Any SQL statement that tries to use an index that is in an Index Unusable state returns an error. The following conditions cause a direct path load to leave an index or a partition of a partitioned index in an Index Unusable state:

* SQL*Loader runs out of space for the index and cannot update the index.
* The data is not in the order specified by the SORTED INDEXES clause.
* There is an instance failure, or the Oracle shadow process fails while building the index.
* There are duplicate keys in a unique index.
* Data savepoints are being used, and the load fails or is terminated by a keyboard interrupt after a data savepoint occurred.

参考文档:
https://docs.oracle.com/cd/B28359_01/server.111/b28319/ldr_modes.htm#i1010480

相关文章
|
4月前
|
存储 关系型数据库 索引
10. 在一个非主键字段上创建了索引, 想要根据该字段查询到数据, 需要查询几次 ?
在非主键字段上创建索引,查询数据通常需两次。对于MyISAM,先通过索引找到数据行指针,再获取数据;而InnoDB则先找主键ID,再从主键索引中查找数据。
28 0
|
9月前
|
SQL 索引
加唯一索引时候发现已有重复数据删除
加唯一索引时候发现已有重复数据删除
37 1
|
SQL 分布式计算 MaxCompute
一次性查询一张表所有字段的空值率
一次性查询一张表所有字段的空值率
1404 2
|
数据库
列的完整性约束——调整列的完整性约束
列的完整性约束——调整列的完整性约束
|
存储 索引
为什么范围后索引会失效 存储引擎不能使用索引中范围条件右边的列
比如说有三个字段 a b c,建立复合索引a_b_c。此时叶子节点的数据排序后可能为
94 0
DataTable 修改列名 删除列 调整列顺序
DataTable 修改列名 删除列 调整列顺序
199 0
|
SQL 算法 测试技术
Guid算法与标识列(自动增长字段)在表中的应用
Guid算法与标识列(自动增长字段)在表中的应用
168 0
Guid算法与标识列(自动增长字段)在表中的应用
|
应用服务中间件 数据库 索引