IN vs OR в предложении SQL WHERE - PullRequest
138 голосов
/ 19 июня 2010

При работе с большими базами данных, которые работают лучше, IN или OR в выражении SQL Where?

Есть ли разница в способе их выполнения?

Ответы [ 6 ]

151 голосов
/ 19 июня 2010

Я предполагаю, что вы хотите знать разницу в производительности между следующими:

WHERE foo IN ('a', 'b', 'c')
WHERE foo = 'a' OR foo = 'b' OR foo = 'c'

В соответствии с руководством для MySQL , если значения постоянны, IN сортирует список, а затемиспользует бинарный поиск.Я полагаю, что OR оценивает их один за другим в произвольном порядке.Так что IN быстрее в некоторых обстоятельствах.

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

Я пробовал оба на MySQL с 1000000 строками.Когда столбец проиндексирован, нет заметной разницы в производительности - оба практически мгновенные.Когда столбец не проиндексирован, я получил следующие результаты:

SELECT COUNT(*) FROM t_inner WHERE val IN (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);
1 row fetched in 0.0032 (1.2679 seconds)

SELECT COUNT(*) FROM t_inner WHERE val = 1000 OR val = 2000 OR val = 3000 OR val = 4000 OR val = 5000 OR val = 6000 OR val = 7000 OR val = 8000 OR val = 9000;
1 row fetched in 0.0026 (1.7385 seconds)

Так что в этом случае метод, использующий OR, примерно на 30% медленнее.Добавление большего количества терминов увеличивает разницу.Результаты могут отличаться для других баз данных и других данных.

32 голосов
/ 19 июня 2010

Лучший способ узнать это - посмотреть на План выполнения.


Я попробовал его с Oracle , и он был точно таким же.

Несмотря на то, что в запросе используется IN, в плане выполнения сказано, что он использует OR:

--------------------------------------------------------------------------------------    
| Id  | Operation         | Name             | Rows  | Bytes | Cost (%CPU)| Time     |    
--------------------------------------------------------------------------------------    
|   0 | SELECT STATEMENT  |                  |     8 |  1416 |   163   (2)| 00:00:02 |    
|*  1 |  TABLE ACCESS FULL| PERFORMANCE_TEST |     8 |  1416 |   163   (2)| 00:00:02 |    
--------------------------------------------------------------------------------------    

Predicate Information (identified by operation id):                                       
---------------------------------------------------                                       

   1 - filter("OBJECT_NAME"='DBMS_LOB' OR "OBJECT_NAME"='DBMS_REGISTRY' OR                
              "OBJECT_NAME"='DBMS_STANDARD')                                              
6 голосов
/ 19 июня 2010

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

Вот пример того, что вы можете использовать с ИЛИ, но которые не совместимы с IN: больше.больше или равно, меньше, меньше или равно, LIKE, а некоторые больше похожи на оракула REGEXP_LIKE.Кроме того, учтите, что условия не всегда могут сравнивать одно и то же значение.

Для оптимизатора запросов проще управлять оператором IN, поскольку это только конструкция, которая определяет оператор OR в нескольких условиях с оператором = втакое же значение.Если вы используете оператор ИЛИ, оптимизатор может не учитывать, что вы всегда используете оператор = для одного и того же значения, и, если он не выполняет более глубокую и очень сложную разработку, он, вероятно, может исключить, что может быть только= операторы для одинаковых значений во всех задействованных условиях с последующим исключением оптимизированных методов поиска, таких как уже упомянутый двоичный поиск.

[EDIT] Вероятно, оптимизатор может не реализовать оптимизированный процесс оценки IN, но это нене исключаю, что один раз это может произойти (с обновлением версии базы данных).Так что если вы используете оператор ИЛИ, то оптимизированная разработка не будет использоваться в вашем случае.

6 голосов
/ 19 июня 2010

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

2 голосов
/ 19 июня 2010

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

Другой альтернативой является использование JOIN с временной таблицей.
Я не думаю, что производительность должна быть проблемой, если у вас есть необходимые индексы.

0 голосов
/ 21 декабря 2016

Я сделал SQL-запрос в большом количестве ИЛИ (350).Postgres делает это 437.80мс .

Use OR

Теперь используйте IN:

Use IN

23,18мс

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...