2015-11-16 4 views
0
id | foo | bar 
-------------- 
0 | 0 | ... 
1 | 1 | ... 
2 | 2 | ... 
3 | 0 | ... 
4 | 2 | ... 

Мне нужны все уникальные значения foo, но не «0», что очень часто.Что происходит быстрее: SELECT DISTINCT или WHERE foo! = 0?

Который быстрее?

SELECT foo FROM `table` WHERE foo != 0 

или

SELECT DISTINCT foo FROM `table` 

Последнее будет держать 0, но будет удален в PHP.

На моем сервере оба были достаточно быстро, но один из этих двух вариант может быть теоретически быстрее :)

+0

В общем DISTINCT стоит дорого.Но для того, чтобы действительно это увидеть, вам нужно 100 k + rows.Also в зависимости от вашего распределения данных, даже первый может быть .low, но, как правило, SELECT DISTINCT без WHERE будет медленным (er) – Mihai

+0

Я смущен. В вашем наборе данных вы знаете, что ненулевые значения DISTINCT или нет? – Strawberry

+0

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

ответ

0

Вот индексный набор данных из 130 000 строк. Редкий столбец имеет значения в диапазоне 0-100000. Плотный столбец имеет значения в диапазоне 0-100.

SELECT * FROM my_table; 
+----+--------+-------+ 
| id | sparse | dense | 
+----+--------+-------+ 
| 1 |  0 |  0 | 
| 2 | 52863 | 87 | 
| 3 | 76503 | 21 | 
| 4 | 77783 | 25 | 
| 6 | 89359 | 73 | 
| 7 | 97772 | 69 | 
| 8 | 53429 | 59 | 
| 9 | 35206 | 99 | 
| 13 | 88062 | 44 | 
| 14 | 56312 | 49 | 
... 

SELECT * FROM my_table WHERE sparse <> 0; 
130941 rows in set (0.09 sec) 

SELECT * FROM my_table WHERE dense <> 0; 
130289 rows in set (0.09 sec) 

SELECT DISTINCT sparse FROM my_table; 
72844 rows in set (0.27 sec) 

SELECT DISTINCT dense FROM my_table; 
101 rows in set (0.00 sec) 

Как вы можете видеть, скорость DISTINCT быстрее зависит от плотности данных.

Очевидно, что в этом случае эти два вопроса сильно отличаются друг от друга!

+0

А, ок, у меня тысячи длинных идентификаторов, как у вас редкий ряд. 10% - «0», некоторые из них удваиваются. В конце концов, мне нужен массив PHP всех уникальных идентификаторов. Я мог бы сохранить удвоение без 0 и очистить массив в PHP? – Martin

+0

Вы могли бы, но не пытаясь, я не мог сказать, будет ли обработка массива в PHP быстрее. Я предполагаю, что этого не будет. – Strawberry

-1
SELECT DISTINCT foo FROM `table` 

, потому что нет Где состояние

+1

Это не отвечает на вопрос. Тот факт, что условие 'where' не существует, уже было задано в вопросе. Пожалуйста, добавьте объяснение, почему отсутствие предложения 'where' является более определяющим, чем включение ключевого слова' distinct'. – trincot

0

В соответствии с условием данного в вопросе, distinct будет быть дорогим, поскольку он сортирует по всем записям в блоке, извлеченном в основной памяти, прежде чем удалять повторяющиеся записи, в то время как select с условием where будет перебирать каждую запись в блоке только один раз, чтобы отфильтровать записи.

Также самый известный алгоритм сортировки делает это в O(nlogn), в то время как итеративная проверка записи происходит в O(n) времени.

Таким образом, первый запрос быстрее здесь.

Надеюсь, он отвечает на ваш вопрос.

0

В большинстве случаев SELECT foo FROM table WHERE foo != 0является быстрее.

Но в вашем случае, это может быть еще быстрее:

SELECT foo FROM `table` WHERE foo > 0 

Из данных вы показали, вы не имеете отрицательные значения, так что вам не нужно проверить для любого. (Как было указано here - MySQL docs - перейдите к разделу комментариев)

От MySQL Distinct docs:

В большинстве случаев DISTINCT положение можно рассматривать как частный случай GROUP BY

Так , если производительность является проблемой, а вы не действительно не нужно, не используйте.

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

  • Нет связанных вопросов^_^