Обновить:
Эта статья в моем блоге обобщает как мой ответ, так и мои комментарии к другим ответам и показывает фактические планы выполнения:
- IN против JOIN и EXISTS
SQL Server
Эти запросы не эквивалентны. Они могут давать разные результаты, если ваша таблица b
не сохранена в ключе (т.е. значения SQL Server
не являются переменными).
Эквивалент первого запроса следующий:
d
Если UNIQUE
есть b
и помечены как таковые (с помощью a
or или INNER JOIN
), то эти запросы идентичны и, скорее всего, будут использовать одинаковые планы, поскольку b
достаточно умен, чтобы принять это во внимание.
SQL Server
может использовать один из следующих методов для запуска этого запроса:
-
Если есть индекс on
b.d
,d
isd
иb
относительно небольшой по сравнению с этимa
, тогда условие распространяется в подзапрос, а plainUNIQUE
используется (сb
ведущим) -
Если есть индекс
LEFT SEMI JOIN
иd
нетUNIQUE
, то условие также распространяется иb.d
используется. Его также можно использовать для вышеуказанного условия. -
Если есть индекс на обоих
a.c
иMERGE SEMI JOIN
они велики, тоb
используется -
Если в любой таблице нет индекса, то используется хэш-таблица
b
иHASH SEMI JOIN
используется.
Ни один из этих методов не пересматривает весь подзапрос каждый раз.
См. Эту запись в своем блоге для более подробной информации о том, как это работает:
- Подсчет отсутствующих строк: SQL Server
Есть ссылки для всех RDBMS
из четырех.