无法合并联合所有视图

发布于 2024-09-24 23:48:38 字数 550 浏览 8 评论 0原文

我知道 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
)

这两个查询是等价的,对吧? [编辑]

I know Oracle RDMS can't merge a view that has a set operator in it. I want to know why is that.

For example, this:

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

could be transformed into this:

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
)

These two queries are equivalent, right?
[edited]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风尘浪孓 2024-10-01 23:48:38

查询将产生相同的结果集,但执行计划可能不同。我希望第一个查询会更高效,因为它与 tab_p 进行比较一次,而与第二个查询中的两次比较。


以前,两个查询都使用 SELECT *,其中都没有表别名。

不,这些查询并不等同。

第一个将从派生表(UNION 语句)和 tab_p 表中返回列。第二个查询将仅返回派生表(UNION 语句)中的值,而不返回 tab_p 表中的列。如果用表别名替换 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 连接语法与第一个查询中使用的 ANSI-89 语法。

The queries will produce the same resultset, but the execution plan is likely to be different. I would expect the first query to be more efficient because it is comparing against tab_p once, vs the two times in the second query.


Previously, both queries used SELECT *, no table alias in either of them.

No, those queries are not equivalent.

The first will return columns from both the derived table (UNION'd statement) and the tab_p table. The second query will only return values from the derived table (UNION'd statement), and no columns from the tab_p table. It's more obvious if you substitute the table aliases in the place of SELECT *:

First query:

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

Second query:

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

There are no tab_p columns in the SELECT clause of the inner query, for the outer query to provide in the ultimate resultset.

This:

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

..is equivalent to the first query. It's using ANSI-92 join syntax vs the ANSI-89 syntax used in the first query.

把人绕傻吧 2024-10-01 23:48:38

您在编辑的问题中描述的转变对我来说似乎是有效的。

Oracle 优化器理论上可以执行许多不同的查询转换,但实际上这仅限于 Oracle 团队实际上费心去实现的那些转换。

如果添加每项转换,都需要在编码和测试方面进行大量投资,并且只有在付费市场中检测到足够的需求时才会进行。

所以,这并不是说它“不能”;而是它“不能”。但目前还没有。

The transformation you describe in your edited question appears valid to me.

There are many many many different query transformations that the Oracle optimizer could in theory perform, but in practice this is limited to those transformations that the Oracle team have actually bothered to implement.

Each transformation, if added, would require a significant investment in coding and testing, and would only be done if sufficient demand was detected in the paying market.

So, it's not that it "can't", necessarily; it just doesn't, yet.

稳稳的幸福 2024-10-01 23:48:38

它们并不等同。第二个查询将失败,因为 u 未定义。

They are not equivalent. The second query will fail, as u is not defined.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文