我知道的Oracle RDMS不能合并具有一组操作者在它的图。我想知道这是为什么。

例如,这样的:

SELECT u.*
FROM
 (
  SELECT a.a1    A,
        a.a2    B
   FROM tab_a a
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b
)     u,
tab_p p
WHERE p.a = u.a

有可能转化为这样:

SELECT *
FROM
 (
  SELECT a.a1    A,
         a.a2    B
    FROM tab_a a,
         tab_p p
   WHERE p.a = a.a1
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b,
         tab_p p
   WHERE p.a = b.b1
)

这两个查询是等效的,是吗? [编辑]

有帮助吗?

解决方案

在你编辑的问题描述转换出现有效的给我。

有很多很多很多不同的查询转换的Oracle优化的在理论上的执行,但在实践中,这仅限于那些转换了Oracle团队的居然不屑于实施

每个转型,如果加的话就需要在编码和测试显著的投资,如果在支付市场被检测到足够的需求只会做。

因此,它不是其“不能”,不一定;它只是不,但

其他提示

在查询将产生相同的结果集,但执行计划很可能是不同的。我期望所述第一查询,以更有效,因为它是针对tab_p在第二查询比较一次,VS的两倍。


此前,这两个查询使用SELECT *,在其中一方。

无表别名

没有,这些查询是不等价的。

第一个将来自两个派生表(语句UNION'd)和tab_p表中返回的列。第二个查询将只从tab_p表中返回派生表(UNION'd语句)值,并没有列。如果您在SELECT *的地方替换表的别名这是比较明显的:

第一查询:

SELECT u.*, p.*
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u,
       tab_p p
 WHERE p.a = u.a

第二查询:

SELECT x.*
 FROM (SELECT a.a1    A,
              a.a2    B
         FROM tab_a a,
              tab_p p
        WHERE p.a = a.a
       UNION ALL
       SELECT b.b1    A,
              b.b2    B
         FROM tab_b b,
              tab_p p
        WHERE p.a = b.a) x

有内部查询的SELECT子句中没有tab_p列,对于外部查询到在最终结果集提供。

此:

SELECT *
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u
  JOIN tab_p p ON p.a = u.a

..是等同于第一查询。它使用ANSI-92联接语法VS在第一查询中使用的ANSI-89的语法。

它们是不等效的。第二次查询将失败,因为u没有定义。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top