не может объединить союз все мнение - PullRequest
3 голосов
/ 28 сентября 2010

Я знаю, что 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
)

Эти два запроса эквивалентны, верно? [Редактировать]

Ответы [ 3 ]

3 голосов
/ 28 сентября 2010

Запросы будут давать один и тот же набор результатов, но план выполнения, вероятно, будет другим.Я ожидал бы, что первый запрос будет более эффективным, потому что он сравнивается с tab_p один раз против двух раз во втором запросе.


Раньше оба запроса использовали SELECT *, псевдоним таблицы влюбой из них.

Нет, эти запросы не эквивалентны.

Первый вернет столбцы как из производной таблицы (оператор UNION'd), так и из таблицы tab_p.Второй запрос будет возвращать только значения из производной таблицы (оператор UNION'd), а не столбцы из таблицы 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

Нетtab_p столбцов в предложении SELECT внутреннего запроса, чтобы внешний запрос предоставлял в конечном наборе результатов.

Это:

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, использованного в первом запросе.

2 голосов
/ 29 сентября 2010

Преобразование, которое вы описываете в своем отредактированном вопросе, кажется мне действительным.

Существует много-много разных преобразований запросов, которые оптимизатор Oracle может в теории выполнить, но на практике этоограничено теми преобразованиями, которые команда Oracle действительно потрудилась реализовать .

Каждое преобразование, если оно будет добавлено, потребует значительных инвестиций в кодирование и тестирование и будет выполнено только при наличии достаточного спросабыл обнаружен на платящем рынке.

Итак, это не значит, что он "не может", обязательно;пока просто нет.

0 голосов
/ 28 сентября 2010

Они не эквивалентны.Второй запрос не будет выполнен, так как u не определено.

...