GROUP BY вместо DISTINCT

-=KPOT=-

Новичок
GROUP BY вместо DISTINCT

Поясню суть вопроса
есть база товаров в ней несколько таблиц есть таблица с фирмами и таблица с товарами
во второй заносится товар и id фирмы
таблицы связаны соотношением один-ко-многим (по id фирмы)
нужно было делать запрос на извлечение фирм для которых есть товары (выбирал этот id из таблицы товаров) простеньким запросом (SELECT * FROM thing GROUP BY id) а потом определял что за фирма так вот GROUP BY делал поскоку про DISTINCT забыл, но результат один и тот же (записи однократные без повторений).
Вопрос на сколько правильный такой подход в целом?
 

Falc

Новичок
-=KPOT=-
В мануале вроде было упоминание, что DISTINCT приводится к GROUP BY, но на моем личном опыте при использовании LIMIT'ов DISTINCT иногда работает быстрее, и по теории баз данных DISTINCT в подобных случаях вроде как грамотней использовать.
Но GROUP BY вроде как универсальнее получатся.
 

Nime

Guest
Originally posted by Falc
-=KPOT=-
В мануале вроде было упоминание, что DISTINCT приводится к GROUP BY, но на моем личном опыте при использовании LIMIT'ов DISTINCT иногда работает быстрее, и по теории баз данных DISTINCT в подобных случаях вроде как грамотней использовать.
Интересно, как у тебя может быть такой личный опыт если explain для обоих запросов даёт одинаковый результат?
 

Falc

Новичок
Nime
А причем тут експлаин?
ты время выполнения запроса по експлайну расчитываешь?

-~{}~ 12.05.04 18:21:

Кстати от LIMIT'а эксплаин не меняется
 

Nime

Guest
А причем тут експлаин?
Время запроса зависит от кучи факторов, но explain показывает как с запросом будет обращаться mysql. А обращаться он в обоих случаях будет одинаково.

Кстати от LIMIT'а эксплаин не меняется
Я обратного и не утверждал.
 

Falc

Новичок
Только что проверил запросы типо:

SELECT a
FROM table
GROUP BY a
LIMIT 20

и

SELECT DISTINCT a
FROM table
LIMIT 20

Где "a" не индексное поле.


В первом случае эксплаин показывает:
Using temporary; Using filesort

Во втором просто:
Using temporary;


При 500 000 записей в таблице разница во времени выполнения запросов в 250 раз В пользу DISTINCT.
 

Nime

Guest
Какая версия mysql? У меня локально 3.23.56

Код:
mysql> explain SELECT a FROM test GROUP BY a LIMIT 20;
+-------+------+---------------+------+---------+------+------+-----------------
+
| table | type | possible_keys | key  | key_len | ref  | rows | Extra
|
+-------+------+---------------+------+---------+------+------+-----------------
+
| test  | ALL  | NULL          | NULL |    NULL | NULL | 1354 | Using temporary
|
+-------+------+---------------+------+---------+------+------+-----------------
+
1 row in set (0.00 sec)

mysql> explain SELECT distinct a FROM test GROUP BY a LIMIT 20;
+-------+------+---------------+------+---------+------+------+-----------------
+
| table | type | possible_keys | key  | key_len | ref  | rows | Extra
|
+-------+------+---------------+------+---------+------+------+-----------------
+
| test  | ALL  | NULL          | NULL |    NULL | NULL | 1354 | Using temporary
|
+-------+------+---------------+------+---------+------+------+-----------------
+
1 row in set (0.00 sec)
--------------------------------


А вот на 4.0.18 на сервере

Код:
mysql> explain SELECT a FROM test GROUP BY a LIMIT 20;
+-------+------+---------------+------+---------+------+--------+---------------------------------+
| table | type | possible_keys | key  | key_len | ref  | rows   | Extra                           |
+-------+------+---------------+------+---------+------+--------+---------------------------------+
| test  | ALL  | NULL          | NULL |    NULL | NULL | 524288 | Using temporary; Using filesort |
+-------+------+---------------+------+---------+------+--------+---------------------------------+
1 row in set (0.00 sec)

mysql> explain SELECT distinct a FROM test GROUP BY a LIMIT 20;
+-------+------+---------------+------+---------+------+--------+---------------------------------+
| table | type | possible_keys | key  | key_len | ref  | rows   | Extra                           |
+-------+------+---------------+------+---------+------+--------+---------------------------------+
| test  | ALL  | NULL          | NULL |    NULL | NULL | 524288 | Using temporary; Using filesort |
+-------+------+---------------+------+---------+------+--------+---------------------------------+
1 row in set (0.00 sec)
----------------------------------

И вот результат запроса

Код:
mysql> select a from test group by a;
+------+
| a    |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.53 sec)

mysql> select distinct a from test;
+------+
| a    |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.51 sec)

mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
|   524288 |
+----------+
1 row in set (0.01 sec)
 

Falc

Новичок
Nime
>>Какая версия mysql?
4.0.18

Ты не те запросы сравниваешь. Там где DISTINCT, GROUP BY не нужен.
 

Nime

Guest
упс, очепятался :)

сейчас проверю

-~{}~ 13.05.04 14:39:

Да, интересно, в 4.0.18 результат отличается от 3.23.x.

В 3.23 результат одинаков, а в 4.0.18 именно так как ты сказал.

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

Но, когда я поставил limit 1 тогда и стала видна разница.

Код:
mysql> SELECT a FROM test GROUP BY a limit 1;
+------+
| a    |
+------+
|    1 |
+------+
1 row in set (0.52 sec)

mysql> SELECT distinct a FROM test limit 1;
+------+
| a    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)
 

Falc

Новичок
Nime
>>Но, когда я поставил limit 1 тогда и стала видна разница.

Вот и я про тоже, разница есть только при использовании LIMIT'а.
Кстати на 4.0.15 сутуация была такая же.
 

Nime

Guest
Да, я же написал, что всё получилось именно так, как ты сказал :)

4.0.15 под рукой нет, но, думаю, что это относится ко всем 4.0.x.
 
Сверху