SQL子查询中多个表的半连接



这个问题是如何解决在子查询中与多个表进行半连接时明显的oracle限制。我有以下两个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.ida.idupdate_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_timed.end_time,除非它们在同一行上。我们传入update_in数组并在这里连接它的原因是,对于每个time/start_time/end_time组合,在循环中运行此查询也证明了性能很差。

除了2个表之外,还有其他原因导致半连接不能工作吗?如果没有,有没有办法绕过这个限制?一些简单的解决方案,我错过了,可以使这些条件工作,而不把2个表在子查询?

正如Bob建议的,您可以使用与update_in数组结构相同的全局临时表(GTT),但关键的区别在于您可以在GTT上创建索引,并且如果您用代表性的示例数据填充GTT,您还可以收集表上的统计信息,以便SQL查询分析器能够更好地预测最佳查询计划。

也就是说,在你的两个查询中还有一些其他显著的差异:

  • 在第一个查询的第一个exists子句中,您引用了两个列start_in和end_in,它们没有表引用。我的猜测是,它们要么是表a或b中的列,要么是sql语句当前范围内的变量。目前还不清楚。
  • 在你的第二个查询中,你引用了列d.time,但是,你没有在第一个查询中使用该列。

将第二个查询更新为以下内容是否会提高它的性能?

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'

相关内容

  • 没有找到相关文章

最新更新