Oracle 唯一约束冲突



我有一个包含超过 3000 万条记录的表。在进行插入时,我需要避免唯一约束冲突。

当我使用这种不存在的方法时,插入需要很长时间。事实上,它在运行 24 小时后无法完成。而且我不能使用ignore_row_on_dupkey_index提示,因为这个表有超过 1 个 PK 列。

另一种选择是插入子集。但是我想知道在我做子设置之前是否有其他方法。

insert into tlb1 a
select * from tlb2 b
where not exists (select 'x' from tlb1 c
where b.pk = c.pk)

重要的决策取决于插入的 numbe rof 行,即表中的行数TBL2

如果这个数字相当低(比如数百到数千(,你可以安全地使用你的方法,前提是PK列上有一个索引 - 谁应该是强制执行唯一约束。

请检查使用的执行计划是否类似于以下执行计划

-------------------------------------------------------------------------------------
| Id  | Operation                | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |          |   110 |  2860 |   113   (0)| 00:00:02 |
|   1 |  LOAD TABLE CONVENTIONAL | TBL1     |       |       |            |          |
|   2 |   NESTED LOOPS ANTI      |          |   110 |  2860 |   113   (0)| 00:00:02 |
|   3 |    TABLE ACCESS FULL     | TBL2     |   110 |  1430 |     3   (0)| 00:00:01 |
|*  4 |    INDEX UNIQUE SCAN     | TBL1_IXD |     1 |    13 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("B"."PK"="C"."PK")

NESTED LOOPS ANTI意味着对于每个插入的行,将执行单个索引查找,以检查目标表中是否已存在该键。

这对于插入的行数量较少的情况很好。对于一个大的插入(数百万行(,优化器将切换到一个HASH JOIN RIGHT ANTI,即两个表中的所有行将被连接以获得可能的重复项。

这可能需要一些时间(但通常不是 24 小时(和 DML 错误日志记录的方法,该方法消除了联接的需要。

INSERT INTO tbl1 (pk)
SELECT pk
FROM   tbl3
LOG ERRORS INTO err$_tbl1 ('dedup tbl3') REJECT LIMIT UNLIMITED;

此方法可以很好地扩展,尤其是当重复项数与插入的行数相比较低时。它与普通刀片相当:

---------------------------------------------------------------------------------
| Id  | Operation                | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |      |   876K|    10M|   427   (1)| 00:00:06 |
|   1 |  LOAD TABLE CONVENTIONAL | TBL1 |       |       |            |          |
|   2 |   TABLE ACCESS FULL      | TBL3 |   876K|    10M|   427   (1)| 00:00:06 |
---------------------------------------------------------------------------------

最新更新