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