Запросы будут давать один и тот же набор результатов, но план выполнения, вероятно, будет другим.Я ожидал бы, что первый запрос будет более эффективным, потому что он сравнивается с 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, использованного в первом запросе.