Фильтрация при соединении?

Есть ли какой-либо аргумент с точки зрения производительности для фильтрации в соединении, а не в предложении WHERE?

Например,

SELECT blah FROM TableA a
INNER JOIN TableB b
ON b.id = a.id
AND b.deleted = 0
WHERE a.field = 5

В отличие от

SELECT blah FROM TableA a
INNER JOIN TableB b
ON b.id = a.id
WHERE a.field = 5
  AND b.deleted = 0

Я лично предпочитаю последнее, потому что считаю, что фильтрацию следует выполнять в разделе фильтрации (ГДЕ), но есть ли какая-либо производительность или другие причины для использования любого метода?


person Craig    schedule 09.02.2011    source источник
comment
дубликат WHERE Clause vs ON при использовании JOIN (да, это включает путешествие во времени, но на первый взгляд ответы немного лучше)   -  person underscore_d    schedule 22.11.2017


Ответы (3)


Если оптимизатор запросов выполняет свою работу, нет никакой разницы (кроме ясности для других) в двух формах внутренних соединений.

Тем не менее, при левых соединениях условие в соединении означает отфильтровывать строки из второй таблицы перед объединением. Условие в where означает отфильтровывать строки из окончательного результата после объединения. Это означает очень разные вещи.

person btilly    schedule 09.02.2011
comment
Оригинальный постер использует внутреннее соединение, а не левое соединение. Как он написал, проблем нет. - person Chogg; 27.03.2018
comment
@Chogg Использование внутреннего соединения в примере не обязательно означает, что вопрос касался только внутренних соединений. - person btilly; 27.03.2018

С внутренними соединениями вы получите те же результаты и, возможно, ту же производительность. Однако с внешними соединениями два запроса будут возвращать разные результаты и совсем не эквивалентны, поскольку помещение условия в предложение where, по сути, изменит запрос с левого соединения на внутреннее (если только вы не ищете записи, в которых некоторые поле пустое).

person HLGEM    schedule 09.02.2011

Между этими двумя нет различий, потому что при логической обработке запроса WHERE всегда будет идти сразу после предложения фильтра (ON), в ваших примерах у вас будет:

  1. Декартово произведение (количество строк из таблицы A x количество строк из таблицы B)
  2. Фильтр (ВКЛ.)
  3. Где.

Ваши примеры соответствуют стандарту ANSI SQL-92, вы также можете написать запрос со стандартом ANSI SQL-89 следующим образом:

SELECT blah FROM TableA a,TableB b
WHERE b.id = a.id AND b.deleted = 0 AND a.field = 5

ЭТО ВЕРНО ДЛЯ ВНУТРЕННИХ СОЕДИНЕНИЙ, С ВНЕШНИМИ СОЕДИНЕНИЯМИ ПОДОБНО, НО НЕ ТАКОЕ

person TheGodfather23    schedule 09.02.2011