Влияет ли порядок соединения в SQL?

Без учета производительности я получу тот же результат из запросов A и B ниже? Как насчет C и D?

-- A
select *
from   a left join b
           on <blahblah>
       left join c
           on <blahblan>


-- B
select *
from   a left join c
           on <blahblah>
       left join b
           on <blahblan>  

-- C
select *
from   a join b
           on <blahblah>
       join c
           on <blahblan>


-- D
select *
from   a join c
           on <blahblah>
       join b
           on <blahblan>  

Ответы

Ответ 1

Для INNER присоединяется, нет, порядок не имеет значения. Запросы будут возвращать одинаковые результаты, если вы измените выбор из SELECT * на SELECT a.*, b.*, c.*.


Для (LEFT, RIGHT или FULL) OUTER присоединяется, да, порядок имеет значение - и ( обновлено) вещи намного сложнее.

Во-первых, внешние объединения не являются коммутативными, поэтому a LEFT JOIN b не совпадает с b LEFT JOIN a

Внешние объединения также не являются ассоциативными, поэтому в ваших примерах, которые включают как свойства (коммутативность, так и ассоциативность):

a LEFT JOIN b 
    ON b.ab_id = a.ab_id
  LEFT JOIN c
    ON c.ac_id = a.ac_id

эквивалентно:

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id

а

a LEFT JOIN b 
    ON  b.ab_id = a.ab_id
  LEFT JOIN c
    ON  c.ac_id = a.ac_id
    AND c.bc_id = b.bc_id

не эквивалентен:

a LEFT JOIN c 
    ON  c.ac_id = a.ac_id
  LEFT JOIN b
    ON  b.ab_id = a.ab_id
    AND b.bc_id = c.bc_id

Другой (надеюсь, более простой) пример ассоциативности. Подумайте об этом как (a LEFT JOIN b) LEFT JOIN c:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id          -- AB condition
 LEFT JOIN c
    ON c.bc_id = b.bc_id          -- BC condition

Этот эквивалентен до a LEFT JOIN (b LEFT JOIN c):

a LEFT JOIN  
    b LEFT JOIN c
        ON c.bc_id = b.bc_id          -- BC condition
    ON b.ab_id = a.ab_id          -- AB condition

только потому, что у нас есть "хорошие" условия ON. Оба ON b.ab_id = a.ab_id и c.bc_id = b.bc_id являются проверками равенства и не включают сравнения NULL.

У вас могут быть даже условия с другими операторами или более сложными типами: ON a.x <= b.x или ON a.x = 7 или ON a.x LIKE b.x или ON (a.x, a.y) = (b.x, b.y), и два запроса будут по-прежнему эквивалентны.

Если, однако, любой из них включает IS NULL или функцию, связанную с нулями типа COALESCE(), например, если условие было b.ab_id IS NULL, то два запроса не были бы эквивалентны.

Ответ 2

для регулярных объединений, это не так. TableA join TableB будет выполнять тот же план выполнения, что и TableB join TableA (поэтому ваши примеры C и D будут одинаковыми)

для объединения слева и справа. TableA left Join TableB отличается от TableB left Join TableA, но его значение равно TableB right Join TableA

Ответ 3

Если вы попытаетесь присоединиться к C на поле из B до присоединения к B, то есть:

SELECT A.x, A.y, A.z FROM A 
   INNER JOIN C
       on B.x = C.x
   INNER JOIN b
       on A.x = B.x

Ваш запрос не будет выполнен, поэтому в этом случае порядок имеет значение.

Ответ 4

Оптимизатор Oracle выбирает порядок соединения таблиц для внутреннего соединения. Оптимизатор выбирает порядок объединения таблиц только в простых предложениях FROM. Вы можете проверить документацию оракула на их сайте. А для левого, правого внешнего соединения самый голосующий ответ - правильный. Оптимизатор выбирает оптимальный порядок соединения, а также оптимальный индекс для каждой таблицы. Порядок соединения может влиять на то, какой индекс является лучшим выбором. Оптимизатор может выбрать индекс в качестве пути доступа к таблице, если это внутренняя таблица, но не если это внешняя таблица (и дальнейших уточнений нет).

Оптимизатор выбирает порядок объединения таблиц только в простых предложениях FROM. Большинство объединений с использованием ключевого слова JOIN объединяются в простые объединения, поэтому оптимизатор выбирает их порядок объединения.

Оптимизатор не выбирает порядок соединения для внешних объединений; он использует порядок, указанный в заявлении.

При выборе порядка соединения оптимизатор принимает во внимание: размер каждой таблицы. Индексы, доступные для каждой таблицы. Полезен ли индекс для таблицы в определенном порядке соединения. Количество строк и страниц, которые нужно отсканировать для каждой таблицы в каждой таблице. объединить заказ