Подтвердить что ты не робот

Различия в производительности между равными (=) и IN с одним значением

Как отличаются SQL-механизмы, когда мы используем знак равенства, а оператор IN имеет одинаковое значение? Изменяется ли время выполнения?

1-й, используя оператор проверки равенства

WHERE column_value = 'All'

2nd, используя оператор OR и одно значение

WHERE column_value IN ('All')

Изменяет ли SQL-механизм IN на = только одно значение?

Есть ли разница в том же в MySQL и PostgreSQL?

4b9b3361

Ответ 1

Нет никакой разницы между этими двумя утверждениями, и оптимизатор преобразует IN в =, когда IN имеет только один элемент в нем.

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

После большого поиска в Интернете я нашел документ на SQL для поддержки этого (я предполагаю, что он применим ко всем СУБД):

Если в круглой скобке есть только одно значение, это commend эквивалентно

WHERE "column_name" = 'value1

Вот ссылка на документ.

Вот план выполнения обоих запросов в Oracle (большинство СУБД будет обрабатывать это же):

EXPLAIN PLAN FOR
select * from dim_employees t
where t.identity_number = '123456789'

Plan hash value: 2312174735
-----------------------------------------------------
| Id  | Operation                   | Name          |
-----------------------------------------------------
|   0 | SELECT STATEMENT            |               |
|   1 |  TABLE ACCESS BY INDEX ROWID| DIM_EMPLOYEES |
|   2 |   INDEX UNIQUE SCAN         | SYS_C0029838  |
-----------------------------------------------------

И для IN():

EXPLAIN PLAN FOR
select * from dim_employees t
where t.identity_number in('123456789');

Plan hash value: 2312174735
-----------------------------------------------------
| Id  | Operation                   | Name          |
-----------------------------------------------------
|   0 | SELECT STATEMENT            |               |
|   1 |  TABLE ACCESS BY INDEX ROWID| DIM_EMPLOYEES |
|   2 |   INDEX UNIQUE SCAN         | SYS_C0029838  |
-----------------------------------------------------

Как вы можете видеть, оба они одинаковы. Это находится в индексированном столбце. То же самое касается неиндексированного столбца (просто полное сканирование таблицы).

Ответ 2

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

Есть ли разница в том же в Mysql и PostgresSQL?

Нет, это не имело бы никакого значения для двух движков (Infact он был бы таким же для большинства баз данных, включая SQL Server, Oracle и т.д.). Оба двигателя преобразуют IN в =

Ответ 3

На самом деле нет больших различий, но если ваш column_value индексирован, оператор IN не может читать его как индекс.

Однажды встретила эту проблему, поэтому будьте осторожны.

Ответ 4

Научите человека ловить рыбу и т.д. Здесь, как увидеть сами, какие варианты ваших запросов будут делать:

mysql> EXPLAIN SELECT * FROM sentence WHERE sentence_lang_id = "AMH"\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: sentence
         type: ref
possible_keys: sentence_lang_id
          key: sentence_lang_id
      key_len: 153
          ref: const
         rows: 442
        Extra: Using where

И попробуем другое:

mysql> EXPLAIN SELECT * FROM sentence WHERE sentence_lang_id in ("AMH")\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: sentence
         type: ref
possible_keys: sentence_lang_id
          key: sentence_lang_id
      key_len: 153
          ref: const
         rows: 442
        Extra: Using where

Вы можете прочитать здесь о том, как интерпретировать результаты запроса mysql EXPLAIN. Напомним, что мы получили идентичный вывод для обоих запросов: создается тот же самый "план выполнения". Строка type сообщает нам, что запрос использует неидеальный индекс (в этом случае внешний ключ), а строка ref сообщает нам, что запрос выполняется путем сравнения значения константы с этим индексом.

Ответ 5

Для отдельного пункта IN нет никакой разницы. Ниже приведена демонстрация использования таблицы EMPS, которая у меня есть.

select * from emps where empid in (1)
select * from emps where empid=1

Предикат для первого запроса в плане выполнения:

[PerformanceV3].[dbo].[Emps].[empID]=CONVERT_IMPLICIT(int,[@1],0)

Предикат для второго запроса в плане выполнения:

[PerformanceV3].[dbo].[Emps].[empID]=CONVERT_IMPLICIT(int,[@1],0)

Если у вас есть несколько значений в IN Clause, лучше их преобразовать в объединение

Ответ 6

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

При этом многие запросы эквивалентны (один и тот же набор результатов), но только из-за ограничений, которые сама база данных не знает, поэтому будьте осторожны в этих случаях (например, для поля флага с цифрами 1-6, db doesn ' t know <3 совпадает с in (1,2)). Но в конце дня, если вы просто думаете о удобочитаемости операторов and и or, это не повлияет на производительность, как вы их пишете.

Ответ 7

Вам нужно будет запустить план выполнения для обоих и посмотреть результаты.

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

Нет никаких причин, по которым оптимизатор будет вести себя иначе по запросу, подобному этому.