Имеет ли значение порядок соединения в 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>  

3 ответа

Решение

За 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, тогда два запроса не будут эквивалентны.

Если вы попытаетесь присоединиться к 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

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

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

для левого и правого присоединения это делает. TableA left Join TableB отличается от TableB left Join TableA, Но это то же самое, что TableB right Join TableA

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

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

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

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

Другие вопросы по тегам