Ответ 1
EXISTS
будет быстрее, потому что, как только двигатель обнаружит удар, он перестанет выглядеть, поскольку условие подтвердилось.
С IN
он будет собирать все результаты из подзапроса перед дальнейшей обработкой.
Мне интересно, что из следующего ниже будет более эффективным?
Я всегда был немного осторожен с использованием 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])
EXISTS
будет быстрее, потому что, как только двигатель обнаружит удар, он перестанет выглядеть, поскольку условие подтвердилось.
С IN
он будет собирать все результаты из подзапроса перед дальнейшей обработкой.
Я провел некоторое тестирование на SQL Server 2005 и 2008, а на обоих EXISTS и IN вернулся с тем же самым фактическим планом выполнения, как и другие. Оптимизатор является оптимальным.:)
Что-то, что нужно знать, хотя, EXISTS, IN и JOIN иногда могут возвращать разные результаты, если вы не будете правильно формулировать свой запрос: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx
Принятый ответ близорук, и вопрос немного расплывчатый:
1) Никоим образом не упоминается, присутствует ли индекс покрытия в левой, правой или обеих сторон.
2) Не учитывается размер входного левого набора и ввод правая сторона комплект.
(В вопросе просто упоминается общий большой набор результатов).
Я считаю, что оптимизатор достаточно умен, чтобы конвертировать между "in" и "существует", когда существует значительная разница в стоимости из-за (1) и (2), в противном случае это может быть просто использовано как подсказка (например, существует поощрять использование поискового индекса на правой стороне).
Обе формы могут быть преобразованы в формы объединений внутри, имеют порядок обращения в обратном порядке и выполняются как цикл, хеш или слияние - на основе оцененных строк строк (слева и справа) и существования индекса в левом, правом или обоих стороны.
Я бы пошел с EXISTS через IN, см. ниже ссылку:
Планы выполнения, как правило, будут одинаковыми в этих случаях, но пока вы не увидите, как факторы оптимизатора во всех других аспектах индексов и т.д., вы действительно никогда не узнаете.
Таким образом, IN - это не то же самое, что EXISTS, и он не будет выполнять один и тот же план выполнения.
Обычно EXISTS используется в коррелированном подзапросе, что означает, что вы присоедините внутренний запрос EXISTS к вашему внешнему запросу. Это добавит больше шагов для получения результата, поскольку вам необходимо решить внешние соединения запросов и внутренние соединения запросов, а затем сопоставить их, где предложения, чтобы присоединиться к ним.
Обычно IN используется без корреляции внутреннего запроса с внешним запросом, и его можно решить всего за один шаг (в лучшем случае).
Учти это:
Если вы используете IN, а результат внутреннего запроса - это миллионы строк различных значений, он, вероятно, будет выполнять SLOWER, чем EXISTS, учитывая, что запрос EXISTS является исполнительным (имеет правильные индексы для соединения с внешним запросом).
Если вы используете EXISTS и соединение с внешним запросом является сложным (требуется больше времени для выполнения, нет подходящих индексов), он замедляет запрос по количеству строк во внешней таблице, иногда расчетное время для завершения может быть в днях. Если количество строк приемлемо для данного оборудования или правильность данных (например, меньше значений DISTINCT в большом наборе данных), IN может работать быстрее, чем EXISTS.
Все вышесказанное будет отмечено, когда у вас есть достаточное количество строк в каждой таблице (честно говоря, я имею в виду что-то, что превышает вашу обработку процессора и/или пороговые значения для кэширования).
Поэтому ОТВЕТ ОТНОСИТСЯ. Вы можете написать сложный запрос внутри IN или EXISTS, но, как правило, вы должны попытаться использовать IN с ограниченным набором различных значений и EXISTS, когда у вас много строк с множеством различных значений.
Хитрость заключается в том, чтобы ограничить количество проверяемых строк.
С Уважением,
MarianoC
Чтобы оптимизировать EXISTS
, будьте очень буквальными; что-то просто должно быть там, но на самом деле вам не нужны какие-либо данные, возвращенные из коррелированного подзапроса. Вы просто оцениваете логическое состояние.
Итак:
WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
Поскольку коррелированный подзапрос RBAR
, первый результат приводит к тому, что условие истинно, и оно не обрабатывается далее.
Здесь есть много вводящих в заблуждение ответов, в том числе и высокоподдерживаемый (хотя я не верю, что их 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)
Сверху моей головы и не гарантируется правильность: я считаю, что второй будет быстрее в этом случае.
IN
будет замыкаться, как только он найдет совпадение.