Oracle - 基于与其他两个表的连接进行删除

时间:2016-02-08 15:45:25

标签: sql oracle join sql-delete

我在设计能够快速运行的代码时遇到一些麻烦。

我的要求是:

我有一张表SCD(180mil记录)和一个较小的表LOG(约300条记录)。

LOG结构:

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包含大量记录。

任何帮助都会得到满足。

2 个答案:

答案 0 :(得分:2)

首先确定应删除哪些密钥。

如果您只想删除SCD中存在real_key的{​​{1}},则如下所示:

fic_key

删除不是

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

如果在SCD中有一个关于serial_key的索引,则删除将通过两个NL连接完成,这应该是非常即时的。 如果没有使用带有小表的SCD表的两个散列连接估计性能。这不应该是180M行的年龄。您也可以使用并行散列连接加速。

答案 1 :(得分:0)

好吧,我已经设法得到了答案。我将解释逻辑:

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

这会导致一些问题,当每个真正的序列作为一个新行出现,并作为新记录插入到我们的SCD表中而不是更新现有的序列时,所以我们必须重建我们的表,以便它们在几个晚前之前。 / p>

最佳和最快的删除查询是:

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)