Производительность SQL Server IN и EXISTS

Мне интересно, что из следующего ниже будет более эффективным?

Я всегда был немного осторожен с использованием IN потому что я считаю, что SQL Server превращает набор результатов в большой оператор IF. Для большого набора результатов это может привести к снижению производительности. Для небольших наборов результатов я не уверен, что либо предпочтительнее. Для больших наборов результатов, EXISTS не будет более эффективным?

WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

против

WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])

Ответ 1

EXISTS будет быстрее, потому что, как только двигатель обнаружит удар, он перестанет выглядеть, поскольку условие подтвердилось.

С IN он будет собирать все результаты из подзапроса перед дальнейшей обработкой.

Ответ 2

Я провел некоторое тестирование на SQL Server 2005 и 2008, а на обоих EXISTS и IN вернулся с тем же самым фактическим планом выполнения, как и другие. Оптимизатор является оптимальным.:)

Что-то, что нужно знать, хотя, EXISTS, IN и JOIN иногда могут возвращать разные результаты, если вы не будете правильно формулировать свой запрос: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

Ответ 3

Принятый ответ близорук, и вопрос немного расплывчатый:

1) Никоим образом не упоминается, присутствует ли индекс покрытия в левой, правой или обеих сторон.

2) Не учитывается размер входного левого набора и ввод правая сторона комплект.
      (В вопросе просто упоминается общий большой набор результатов).

Я считаю, что оптимизатор достаточно умен, чтобы конвертировать между "in" и "существует", когда существует значительная разница в стоимости из-за (1) и (2), в противном случае это может быть просто использовано как подсказка (например, существует поощрять использование поискового индекса на правой стороне).

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

Ответ 5

Планы выполнения, как правило, будут одинаковыми в этих случаях, но пока вы не увидите, как факторы оптимизатора во всех других аспектах индексов и т.д., вы действительно никогда не узнаете.

Ответ 6

Таким образом, IN - это не то же самое, что EXISTS, и он не будет выполнять один и тот же план выполнения.

Обычно EXISTS используется в коррелированном подзапросе, что означает, что вы присоедините внутренний запрос EXISTS к вашему внешнему запросу. Это добавит больше шагов для получения результата, поскольку вам необходимо решить внешние соединения запросов и внутренние соединения запросов, а затем сопоставить их, где предложения, чтобы присоединиться к ним.

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

Учти это:

  1. Если вы используете IN, а результат внутреннего запроса - это миллионы строк различных значений, он, вероятно, будет выполнять SLOWER, чем EXISTS, учитывая, что запрос EXISTS является исполнительным (имеет правильные индексы для соединения с внешним запросом).

  2. Если вы используете EXISTS и соединение с внешним запросом является сложным (требуется больше времени для выполнения, нет подходящих индексов), он замедляет запрос по количеству строк во внешней таблице, иногда расчетное время для завершения может быть в днях. Если количество строк приемлемо для данного оборудования или правильность данных (например, меньше значений DISTINCT в большом наборе данных), IN может работать быстрее, чем EXISTS.

  3. Все вышесказанное будет отмечено, когда у вас есть достаточное количество строк в каждой таблице (честно говоря, я имею в виду что-то, что превышает вашу обработку процессора и/или пороговые значения для кэширования).

Поэтому ОТВЕТ ОТНОСИТСЯ. Вы можете написать сложный запрос внутри IN или EXISTS, но, как правило, вы должны попытаться использовать IN с ограниченным набором различных значений и EXISTS, когда у вас много строк с множеством различных значений.

Хитрость заключается в том, чтобы ограничить количество проверяемых строк.

С Уважением,

MarianoC

Ответ 7

Чтобы оптимизировать EXISTS, будьте очень буквальными; что-то просто должно быть там, но на самом деле вам не нужны какие-либо данные, возвращенные из коррелированного подзапроса. Вы просто оцениваете логическое состояние.

Итак:

WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

Поскольку коррелированный подзапрос RBAR, первый результат приводит к тому, что условие истинно, и оно не обрабатывается далее.

Ответ 8

Здесь есть много вводящих в заблуждение ответов, в том числе и высокоподдерживаемый (хотя я не верю, что их ops означал вред). Короткий ответ: это то же самое.

Существует много ключевых слов на языке SQL (T-), но в конце, единственное, что действительно происходит на аппаратном обеспечении, - это операции, которые видны в плане выполнения выполнения.

Реляционная (математическая теория), которую мы выполняем при вызове [NOT] IN и [NOT] EXISTS - это полусоединение (anti- присоединяется при использовании NOT). Совсем не случайно, что соответствующие операции с SQL-сервером имеют одинаковое имя. Нет операции, в которой упоминаются IN или EXISTS любом месте - только (anti-). Таким образом, нет никакого способа, чтобы логически эквивалентный выбор IN vs EXISTS мог повлиять на производительность, потому что есть один и единственный способ выполнения (анти) получленов для получения их результатов.

Пример:

Запрос 1 (план)

select * from dt where dt.customer in (select c.code from customer c where c.active=0)

Запрос 2 (план)

select * from dt where exists (select 1 from customer c where c.code=dt.customer and c.active=0)

Ответ 9

Сверху моей головы и не гарантируется правильность: я считаю, что второй будет быстрее в этом случае.

  • В первом случае коррелированный подзапрос, вероятно, вызовет запуск подзапроса для каждой строки.
  • Во втором примере подзапрос должен выполняться только один раз, поскольку не коррелирован.
  • Во втором примере IN будет замыкаться, как только он найдет совпадение.