【发布时间】:2015-06-03 23:37:29
【问题描述】:
这个问题是如何解决在子查询中使用多个表进行半连接时明显的 oracle 限制。我有以下 2 个 UPDATE 语句。
更新 1:
UPDATE
(SELECT a.flag update_column
FROM a, b
WHERE a.id = b.id AND
EXISTS (SELECT NULL
FROM c
WHERE c.id2 = b.id2 AND
c.time BETWEEN start_in AND end_in) AND
EXISTS (SELECT NULL
FROM TABLE(update_in) d
WHERE b.time BETWEEN d.start_time AND d.end_time))
SET update_column = 'F'
执行计划表明这正确执行了 2 个半连接,并且更新在几秒钟内执行。这些需要半连接,因为c.id2 不是b.id2 上的唯一外键,这与b.id 和a.id 不同。而update_in 根本没有任何约束,因为它是一个数组。
更新 2:
UPDATE
(SELECT a.flag update_column
FROM a, b
WHERE a.id = b.id AND
EXISTS (SELECT NULL
FROM c, TABLE(update_in) d
WHERE c.id2 = b.id2 AND
c.time > d.time AND
b.time BETWEEN d.start_time AND d.end_time))
SET update_column = 'F'
这不做半连接;我相信基于 Oracle 文档,这是因为 EXISTS 子查询中有 2 个表。由于表的大小和分区,此更新需要数小时。但是,除了位于同一行之外,无法将 d.time 与关联的 d.start_time 和 d.end_time 相关联。而我们之所以传入update_in 数组并在这里加入它,是因为在循环中针对每个 time/start_time/end_time 组合运行此查询也证明性能很差。
除了 2 个表之外,还有其他原因导致半连接无法正常工作吗?如果没有,有没有办法绕过这个限制?我缺少一些简单的解决方案,可以在不将 2 个表放入子查询的情况下使这些条件起作用?
【问题讨论】:
-
我怀疑使用数组。我建议不要尝试将数组视为表,而是创建一个全局临时表(具有适当的索引),用
update_in的值填充它,然后在临时表上进行连接。祝你好运。 -
包含与
update_in相同值的全局临时表仍需要半联接。