Oracle - 基于与另外两个表的连接删除

Oracle - delete based on join with two other tables

我在设计 运行 快速的代码时遇到了一些问题。

我的要求是:

我有一个 table SCD(1.8 亿条记录)和一个较小的 table LOG(大约 300 条记录)。

日志结构:

REAL_KEY | FIC_KEY

SCD 结构:

Another_KEY | SERIAL_KEY ....

我需要从 SCD 中删除所有真正的密钥,其中还存在一条带有 FIC_KEY 的记录,所以类似于

delete from scd t
where serial_number in(select real_key from log l1)
and exists(select 1 from scd s,log l2 where s.serial_key = l2.fic_key
           and l2.real_key = l1.real_key)

问题是我无法使用第一个相关查询结果来比较第二个 (l2.real_key = l1.real_key)。另外,即使它 运行,这也可能会花费很多时间,因为 SCD 包含很多记录。

如有任何帮助,我们将不胜感激。

首先决定应该删除哪些键。

如果只想删除SCD中存在fic_keyreal_key个,如下:

select real_key 
from log join scd on log.fic_key = scd.serial_key

删除比

delete from scd where serial_key in ( 
select real_key 
from log join scd on log.fic_key = scd.serial_key); 

如果您在 SCD 中的 serial_key 上有一个索引,删除将通过两个 NL 连接完成,这应该是非常即时的。 如果否,则使用 SCD table 的两个散列连接和小的 table 来估计性能。这不应该是 180M 行的年龄。您还可以使用并行散列连接加快速度。

好吧,我已经想出了答案。我来解释一下逻辑:

我们在过去的几个晚上遇到了一个错误,当时我们的消息来源向我们提供了新的 REAL 序列数据,并且由于一个问题我们禁用了我们的流程修复我们数据仓库中的那些序列号。

这导致了一些问题,当每个真正的序列号作为一个新行出现时,并作为新记录插入到我们的 SCD 表中,而不是更新现有的序列号,所以我们不得不将我们的表重建为几天前的样子.

最好最快的删除查询是:

delete from scd t
where t.serial_number in(select s.real_serial_number
                         from UPD_SERIAL s,scd t2
                         where t2.serial_number = s.fic_serial_number)