Мне любопытно, что из следующего было бы более эффективным?
Я всегда был немного осторожен в использовании, 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])
sql-server
sql-server-2005
exists
query-performance
sql-in
Рэнди Миндер
источник
источник
select 1 from Base...
в своем,where exists
поскольку на самом деле вам не важны результаты, а просто то, что строка действительно существует.Ответы:
EXISTS
будет быстрее, потому что, как только двигатель обнаружит попадание, он перестанет искать, поскольку условие подтвердилось.При наличии
IN
он соберет все результаты подзапроса перед дальнейшей обработкой.источник
Принятый ответ недальновиден, и вопрос в этом немного расплывчатый:
Я считаю, что оптимизатор достаточно умен, чтобы конвертировать между «в» и «существует», когда существует значительная разница в стоимости из-за (1) и (2), в противном случае он может использоваться просто как подсказка (например, существует для поощрения использования индекс с возможностью поиска справа).
Обе формы могут быть преобразованы в формы соединения внутренне, иметь обратный порядок соединения и запускаться как цикл, хэш или слияние - в зависимости от предполагаемого количества строк (слева и справа) и наличия индекса слева, справа или с обеих сторон.
источник
IN
иEXISTS
. Попробуйте придумать любой случай, когда у них другой план (хотя это не относится кNOT IN
иNOT EXISTS
)Я провел некоторое тестирование SQL Server 2005 и 2008, и как EXISTS, так и IN вернулись с точно таким же фактическим планом выполнения, как утверждали другие. Оптимизатор оптимален. :)
Однако следует помнить о том, что EXISTS, IN и JOIN могут иногда возвращать разные результаты, если вы неправильно формулируете свой запрос: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210 .aspx
источник
Здесь есть много вводящих в заблуждение ответов, в том числе один, получивший высокую оценку (хотя я не верю, что их операции навредили). Короткий ответ: это то же самое.
В языке (T-) SQL есть много ключевых слов, но, в конце концов, единственное, что действительно происходит на оборудовании, - это операции, указанные в плане выполнения запроса.
Операция отношения (математическая теория), которую мы выполняем, когда мы вызываем,
[NOT] IN
и[NOT] EXISTS
является полусоединением (антисоединением при использованииNOT
). Неслучайно соответствующие операции sql-сервера имеют одно и то же имя . Нет операции, которая упоминаетIN
илиEXISTS
где-либо - только (анти) полусоединения. Таким образом, нет никакого способа, чтобы логически эквивалентный выборIN
vsEXISTS
мог повлиять на производительность, потому что есть один и единственный способ, операция выполнения (анти) полусоединения, для получения их результатов. .Пример:
Запрос 1 ( план )
Запрос 2 ( план )
источник
Я бы выбрал EXISTS через IN, см. Ссылку ниже:
SQL Server: JOIN vs IN vs EXISTS - логическая разница
Автор блога: https://stackoverflow.com/users/31345/mladen-prajdic
источник
Планы выполнения в этих случаях обычно будут идентичными, но пока вы не увидите, как оптимизатор учитывает все другие аспекты индексов и т. Д., Вы никогда не узнаете.
источник
Таким образом, IN - это не то же самое, что EXISTS, и он не будет производить тот же план выполнения.
Обычно EXISTS используется в коррелированном подзапросе, что означает, что вы ПРИСОЕДИНЯЕТЕСЬ к внутреннему запросу EXISTS со своим внешним запросом. Это добавит больше шагов для получения результата, так как вам нужно решить соединения внешнего запроса и соединения внутреннего запроса, а затем сопоставить их предложения where для объединения обоих.
Обычно IN используется без корреляции внутреннего запроса с внешним запросом, и это может быть решено всего за один шаг (в лучшем случае).
Учти это:
Если вы используете IN, а результатом внутреннего запроса являются миллионы строк с разными значениями, он, вероятно, будет выполнять МЕНЬШЕ, чем EXISTS, учитывая, что запрос EXISTS является производительным (имеет правильные индексы для соединения с внешним запросом).
Если вы используете EXISTS и соединение с вашим внешним запросом является сложным (требуется больше времени для выполнения, нет подходящих индексов), он замедлит запрос на количество строк во внешней таблице, иногда расчетное время для завершения может быть в днях. Если количество строк приемлемо для вашего оборудования или количество данных правильное (например, меньше значений DISTINCT в большом наборе данных), IN может работать быстрее, чем EXISTS.
Все вышеперечисленное будет отмечено, когда у вас будет достаточное количество строк в каждой таблице (честно говоря, я имею в виду то, что превышает пороги обработки вашего процессора и / или RAM для кэширования).
Итак, ОТВЕТ ЗАВИСИТ. Вы можете написать сложный запрос внутри IN или EXISTS, но, как правило, вы должны попытаться использовать IN с ограниченным набором различных значений и EXISTS, когда у вас много строк с большим количеством различных значений.
Хитрость заключается в том, чтобы ограничить количество сканируемых строк.
С Уважением,
MarianoC
источник
Чтобы оптимизировать
EXISTS
, будьте очень буквальными; что-то просто должно быть там, но на самом деле вам не нужны какие-либо данные, возвращаемые из коррелированного подзапроса. Вы просто оцениваете логическое условие.Так:
WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
Поскольку коррелированный подзапрос равен
RBAR
, первое попадание результата делает условие истинным, и оно больше не обрабатывается.источник
Совершенно неожиданно и не гарантирую, что он верен: я считаю, что в этом случае второй будет быстрее.
IN
произойдет короткое замыкание, как только будет найдено совпадение.источник