2009-12-10 3 views
1
SELECT * FROM table WHERE col IN (1,2,3) 

илиЧто будет быстрее из этих двух запросов?

SELECT * FROM table WHERE col = 1 OR col = 2 OR col = 3 
+6

DB?Вы прокомментировали? – ChaosPandion

+5

Можно ли предположить из его значка дельфина, что он имеет в виду MySQL? ;) –

+0

Считываемость, вероятно, больше стоит проблем, чем за несколько миллисекунд, которые вы сэкономите, используя «лучший» ... – Romain

ответ

5

Они одинаковы.

Редактировать: Они одинаковы в MySQL.

с помощью индекса:

mysql> explain select * from trees where id = 1 or id = 2; 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ 
| 1 | SIMPLE  | trees | range | PRIMARY  | PRIMARY | 8  | NULL | 2 | Using where | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ 

mysql> explain select * from trees where id in (1,2); 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ 
| 1 | SIMPLE  | trees | range | PRIMARY  | PRIMARY | 8  | NULL | 2 | Using where | 
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ 

с использованием полного сканирования таблицы:

mysql> explain select * from trees where version = 1 or version = 2; 
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 
| 1 | SIMPLE  | trees | ALL | NULL   | NULL | NULL | NULL | 7 | Using where | 
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 

mysql> explain select * from trees where version in (1,2); 
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 
| 1 | SIMPLE  | trees | ALL | NULL   | NULL | NULL | NULL | 7 | Using where | 
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 
+0

Это кажется маловероятным. –

+1

Я думал, что 'IN (что угодно)' просто переведен на несколько тестов 'OR', поэтому кажется, что они будут одинаковыми. –

+0

Очень маловероятно, действительно. – Romain

2

Это зависит от интерпретации поставщика базы данных и как они представляют, где заявление.

2

В Microsoft SQL Server я считаю, что они интерпретируются точно так же.

2

Вероятно или нет, но это правда ... Большинство баз данных преобразуют прежний синтаксис в последний. Почему бы и нет? Они логически и функционально идентичны.

См here

+0

Потому что могут быть более быстрые способы сделать это в зависимости от того, как данные представлены внутри, и как проектируется двигатель. Разумеется, разница будет минималистичной. – Romain

+0

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

+0

Чтобы сделать абсолютно идентичную аналогию, было бы так, как если бы язык позволял вам либо говорить «Where ColumnName =« bob », либо« Where ColumnName равно «bob» «--------» или, и это IS случай во многих базах данных «Where ColumnName! =« Bob »или« Where ColumnName <> «bob» « –

3

В большинстве РСУБД запросы обрабатываются через оптимизатор перед выполнением. И так как ваши предикаты логически эквивалентны, я бы ожидал, что они будут выполняться с одинаковой скоростью, потому что они будут оптимизированы для выполнения таким же образом.

Но это зависит от db. Вы не указали, какой движок вы используете.

2

Запустите EXPLAIN SELECT ... на обоих.

+0

+1. Выясните, являются ли они разными или одинаковыми. –

0

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

2

Правильный ответ: зависит от двигателя. Используйте EXPLAIN, чтобы проверить, что происходит.

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

Postgres, например, дает более низкую (!) Стоимость при использовании формы IN.

Я лично хотел бы получить первую форму, поскольку (1) некоторые двигатели могут ее оптимизировать, (2) больше интуитивно понятный, (3) короче.

В некоторой степени оффтоп: пожалуйста, не соблазняйтесь чрезмерно использовать IN для соединения таблиц. Я видел много раз конструктов, как это:

SELECT * FROM работника WHERE boss_id IN (SELECT ID FROM боссу WHERE some_condition ..)

Я думаю, причина этого в том, что кто-то идет с наружной выбора, затем выясняет условие в ссылочной таблице, выдавая внутренний выбор, а затем копирует только &. Конечно, такая конструкция хуже, чем правильное СОЕДИНЕНИЕ.

+0

И почему оптимизатор не может сгладить это соединение? – tster

Смежные вопросы