czwartek, 8 grudnia 2011

Distinct vs group by

Miałem dziś w pracy małą zagwozdkę.
Mianowicie serwer zaczał się dusić przy pewnym zapytaniu. Po modyfikacji skryptu udało mi się końcowe zapytnie ograniczyć do

mysql> select count(*) from kontrakty;
+----------+
| count(*) |
+----------+
|   224407 | 
+----------+

mysql> select count(*) from users;
+----------+
| count(*) |
+----------+
|      630 | 
+----------+


select sql_no_cache distinct CONCAT(u.nazwisko,' ',u.imie) from kontrakty sk  join users u on (u.id_user=sk.id_user_realizacja)  order by nazwisko,imie;
91 rows in set (0.85 sec)

Niby fajnie czas spadł z ~4s do 0.85s ale ciągle wydawało mi się to zbyt długo.
Z czytania describe''a jestem cienki jak polsilver:

mysql> desc select sql_no_cache distinct CONCAT(u.nazwisko,' ',u.imie) from kontrakty sk  join sers u on (u.id_user=sk.id_user_realizacja)  order by nazwisko,imie; 
+----+-------------+-------+--------+----------------------------------------+---------------------+---------+---------------------------------+--------+----------------------------------------------+
| id | select_type | table | type   | possible_keys                          | key                 | key_len | ref                             | rows   | Extra                                        |
+----+-------------+-------+--------+----------------------------------------+---------------------+---------+---------------------------------+--------+----------------------------------------------+
|  1 | SIMPLE      | sk    | index  | skontrakty_FKIndex3,id_user_realizacja | skontrakty_FKIndex3 | 4       | NULL                            | 217875 | Using index; Using temporary; Using filesort | 
|  1 | SIMPLE      | u     | eq_ref | PRIMARY                                | PRIMARY             | 4       | sk.id_user_realizacja |      1 |                                              | 
+----+-------------+-------+--------+----------------------------------------+---------------------+---------+---------------------------------+--------+----------------------------------------------+

Trochę pokombinowałem i nagle wpadłem na pomysł, zeby użyć group by. Efekt był pozytywnie zaskakujący : 91 rows in set (0.12 sec)

mysql> desc select sql_no_cache CONCAT(u.nazwisko,' ',u.imie) from kontrakty sk  join users u on (u.id_user=sk.id_user_realizacja)  group by u.id_user order by nazwisko,imie;
+----+-------------+-------+-------+----------------------------------------+--------------------+---------+--------------------+------+---------------------------------+
| id | select_type | table | type  | possible_keys                          | key                | key_len | ref                | rows | Extra                           |
+----+-------------+-------+-------+----------------------------------------+--------------------+---------+--------------------+------+---------------------------------+
|  1 | SIMPLE      | u     | index | PRIMARY                                | PRIMARY            | 4       | NULL               |  763 | Using temporary; Using filesort | 
|  1 | SIMPLE      | sk    | ref   | kontrakty_FKIndex3,id_user_realizacja | id_user_realizacja | 4       | u.id_user |  660 | Using index                     | 
+----+-------------+-------+-------+----------------------------------------+--------------------+---------+--------------------+------+---------------------------------+
Nie ma aż takiego szału ale patrząc na całość (4s->0.12s) to jestem zadowolony.
Jak na razie nie jestem w stanie powiedzieć czemu group by zadziałało szybciej ale w najbliższych planach mam nauczynie czytania się desc'a ;]

Brak komentarzy:

Prześlij komentarz