这个问题是如何解决子查询中具有多个表的半连接的明显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
数组并在此处加入它的原因是因为在每次/ start_time / end_time组合的循环中运行此查询也会导致性能不佳。
除了2个表之外还有一个原因是半连接可能无法正常工作吗?如果没有,是否有办法绕过这个限制?我遗漏的一些简单的解决方案可以使这些标准无需在子查询中放置2个表吗?
答案 0 :(得分:0)
正如Bob建议您可以使用与update_in数组具有相同结构的全局临时表(GTT),但关键区别在于您可以在GTT上创建索引,并且如果使用代表性样本数据填充GTT,您还可以收集表中的统计信息,以便SQL查询分析器能够更好地预测最佳查询计划。
也就是说,您的两个查询中还存在一些其他值得注意的差异:
将第二个查询更新到以下内容会改善它的性能吗?
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 BETWEEN start_in AND end_in AND
c.time > d.time AND
b.time BETWEEN d.start_time AND d.end_time))
SET update_column = 'F'