Мне интересно, есть ли разница в производительности между следующими
SELECT ... FROM ... WHERE someFIELD IN(1,2,3,4)
SELECT ... FROM ... WHERE someFIELD between 0 AND 5
SELECT ... FROM ... WHERE someFIELD = 1 OR someFIELD = 2 OR someFIELD = 3 ...
или MySQL оптимизирует SQL так же, как компиляторы оптимизируют код?
РЕДАКТИРОВАТЬ: Изменил AND
'ы OR
' по причине, указанной в комментариях.
mysql
sql
performance
optimization
Скотт
источник
источник
s I could say that it can also be converted to UNION
которая рекомендуется для замены OR для оптимизации запроса.Ответы:
Мне нужно было знать это наверняка, поэтому я сравнил оба метода. Я последовательно обнаружил,
IN
что гораздо быстрее, чем с помощьюOR
.Не верьте людям, которые высказывают свое «мнение», наука - это все о проверках и доказательствах.
Я запустил цикл 1000x эквивалентных запросов (для согласованности я использовал
sql_no_cache
):IN
: 2.34969592094sOR
: 5.83781504631sОбновление:
(У меня нет исходного кода для исходного теста, как это было 6 лет назад, хотя он возвращает результат в том же диапазоне, что и этот тест)
В запросе некоторого примера кода, чтобы проверить это, вот самый простой возможный вариант использования. Используя Eloquent для простоты синтаксиса, аналог SQL-кода выполняет то же самое.
источник
IN
оператор был примерно на 30% быстрее, чем операторOR
.Do not believe people who give their "opinion"
Вы на 100% правы, к сожалению, переполнение стека ихReturns 1 if expr is equal to any of the values in the IN list, else returns 0. If all values are constants, they are evaluated according to the type of expr and sorted. The search for the item then is done using a binary search. This means
IN is very quick if the IN value list consists entirely of constants
. Otherwise, type conversion takes place according to the rules described at Type Conversion, but applied to all the arguments.
IN
Я также сделал тест для будущих Googlers. Общее количество возвращенных результатов составляет 7264 из 10000
Этот запрос занял
0.1239
секундыЭтот запрос занял
0.0433
секундыIN
в 3 раза быстрее чемOR
источник
OR
: лучше всего использовать наиболее компактное из возможных выражений.Принятый ответ не объясняет причину.
Ниже приведены цитаты из High Performance MySQL, 3-е издание.
источник
Я думаю, что МЕЖДУ будет быстрее, так как он должен быть преобразован в:
Насколько я понимаю, IN все равно будет преобразован в кучу операторов OR. Значение IN - это простота использования. (Экономия на необходимости вводить имя каждого столбца несколько раз, а также упрощает использование с существующей логикой - вам не нужно беспокоиться о приоритете AND / OR, потому что IN - это один оператор. С кучей операторов OR вы получаете чтобы вы заключили их в круглые скобки, чтобы они были оценены как одно условие.)
Единственный реальный ответ на ваш вопрос - ПРОФИЛЬ ВАШИХ ЗАПРОСОВ . Тогда вы будете знать, что работает лучше всего в вашей конкретной ситуации.
источник
Это зависит от того, что вы делаете; насколько широкий диапазон, какой тип данных (я знаю, что в вашем примере используется числовой тип данных, но ваш вопрос также может относиться ко многим различным типам данных).
Это случай, когда вы хотите написать запрос обоими способами; заставить его работать, а затем используйте EXPLAIN, чтобы выяснить различия в исполнении.
Я уверен, что есть конкретный ответ на это, но именно так я бы, практически говоря, выяснил ответ на мой заданный вопрос.
Это может быть полезно: http://forge.mysql.com/wiki/Top10SQLPerformanceTips
С уважением,
Фрэнк
источник
Я думаю, что одним из объяснений наблюдения Sunseeker является то, что MySQL фактически сортирует значения в операторе IN, если они все являются статическими значениями и используют бинарный поиск, который более эффективен, чем простая альтернатива ИЛИ. Я не могу вспомнить, где я это читал, но результат Sunseeker кажется доказательством.
источник
Как раз тогда, когда вы думали, что это безопасно ...
Какова ваша ценность
eq_range_index_dive_limit
? В частности, у вас есть больше или меньше пунктов вIN
предложении?Это не будет включать в себя Benchmark, но немного заглянет во внутреннюю работу. Давайте посмотрим, что происходит, - инструмент Optimizer Trace.
Запрос:
SELECT * FROM canada WHERE id ...
С
OR
3 значениями часть трассировки выглядит так:...
...
Обратите внимание, как дается ICP
ORs
. Это подразумевает, чтоOR
это не превращается вIN
, и InnoDB будет выполнять кучу=
тестов через ICP. (Я не чувствую, что стоит рассмотреть MyISAM.)(Это журнал Percona 5.6.22-71.0;
id
это вторичный индекс.)Теперь для IN () с несколькими значениями
eq_range_index_dive_limit
= 10; Есть 8 значений....
...
Обратите внимание, что
IN
, кажется, не превращается вOR
.Примечание: обратите внимание, что постоянные значения были отсортированы . Это может быть полезно двумя способами:
Наконец, IN () с большим количеством значений
...
...
Примечание: мне это нужно из-за громоздкости следа:
источник
ИЛИ будет самым медленным. Будет ли IN или BETWEEN быстрее, будет зависеть от ваших данных, но я ожидаю, что BETWEEN будет быстрее, как обычно, поскольку он может просто взять диапазон из индекса (при условии, что someField проиндексирован).
источник
Ниже приведены подробности 6 запросов с использованием MySQL 5.6 @SQLFiddle.
Таким образом, 6 запросов охватывают независимо индексируемые столбцы и 2 запроса были использованы для каждого типа данных. Все запросы привели к использованию индекса независимо от используемых IN () или OR.
Я действительно просто хотел опровергнуть сделанные заявления, что ИЛИ означает, что индекс не может быть использован. Это не правда Индексы могут использоваться в запросах с использованием ИЛИ, поскольку отображаются 6 запросов в следующих примерах.
Также мне кажется, что многие проигнорировали тот факт, что IN () является синтаксическим ярлыком для набора OR. В небольших масштабах различия в производительности между использованием IN () -v- ИЛИ чрезвычайно (бесконечно) незначительны.
Хотя в большем масштабе IN (), безусловно, удобнее, но все равно логически соответствует ряду условий OR. Изменение обстоятельств для каждого запроса, поэтому тестирование вашего запроса на ваших таблицах всегда лучше.
Сводка 6 планов объяснения, все «Использование условия индекса» (прокрутка вправо)
SQL Fiddle
Настройка схемы MySQL 5.6 :
,
Запрос 1 :
Результаты :
Запрос 2 :
Результаты :
Запрос 3 :
Результаты :
Запрос 4 :
Результаты :
Запрос 5 :
Результаты :
Запрос 6 :
Результаты :
источник
Могу поспорить, что они одинаковые, вы можете запустить тест, выполнив следующие действия:
переверните "in (1,2,3,4)" 500 раз и посмотрите, сколько времени это займет. переверните версию "= 1 или = 2 или = 3 ..." 500 раз и посмотрите, как долго она работает.
Вы также можете попробовать способ соединения, если someField является индексом, а ваша таблица велика, это может быть быстрее ...
Я попробовал метод объединения выше на моем SQL Server, и он почти такой же, как в (1,2,3,4), и оба они приводят к поиску кластеризованного индекса. Я не уверен, как MySQL справится с ними.
источник
2018 : IN (...) быстрее. Но > = && <= даже быстрее, чем IN .
Вот мой тест .
источник
Из того, что я понимаю о том, как компилятор оптимизирует эти типы запросов, использование предложения IN более эффективно, чем использование нескольких предложений OR. Если у вас есть значения, в которых можно использовать предложение BETWEEN, это еще более эффективно.
источник
Я знаю, что до тех пор, пока у вас есть индекс по полю, МЕЖДУ будет использовать его, чтобы быстро найти один конец, а затем перейти к другому. Это наиболее эффективно.
Каждое ОБЪЯСНЕНИЕ, которое я видел, показывает, что «IN (...)» и «... ИЛИ ...» взаимозаменяемы и одинаково (не) эффективны. Как и следовало ожидать, так как оптимизатор не может знать, содержат ли они интервал или нет. Это также эквивалентно UNION ALL SELECT для отдельных значений.
источник
Как объяснили другие, IN лучше выбирается, чем OR в отношении производительности запросов.
Запросы с условием ИЛИ могут занять больше времени в следующих случаях.
источник