Wykorzystanie zapytania EXPLAIN i przeanalizowanie planu naszego SELECT’a to pierwszy krok, który należy wykonać aby sprawdzić wydajność zapytania. Nie jest to jednak wszystko. MySQL udostępnia dodatkowe mechanizmy, które pokazują, co dokładnie dzieje się z zapytaniem – jak jest wykonywane, jakie operacje są przeprowadzane na tabelach itp.
Pierwszy z tych mechanizmów to profiler. Włączamy go wykonując zapytanie
Zmienna ta ustawiana jest dla sesji, nie dotyczy pozostałych zapytań wykonywanych przez serwer MySQL. Jest to o tyle wygodne, że historia profilera obejmuje maksymalnie 100 zapytań (ustawiane jest to zmienną profiling_history_size) i w przypadku serwera produkcyjnego szybko zostałaby zapełniona. Należy cały czas pamiętać jednak o tym, że pozostałe zapytania także obciążają serwer i mogą doprowadzić do wypaczenia wyników testów. Najlepszym miejscem na tego typu testy wydajności zapytań byłby pusty serwer z zainstalowaną bazą MySQL i odpowiednim zestawem danych.
Po włączeniu profilera wykonujemy interesujące nas zapytanie, a nastepnie poleceniem
sprawdzamy jaki ID zostało przydzielone naszemu zapytaniu.
+----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 1 | 0.00049600 | SELECT SQL_NO_CACHE first_name, last_name, title FROM film LEFT OUTER JOIN film_actor USING (film_id) LEFT OUTER JOIN actor1 USING (actor_id) WHERE first_name='PENELOPE' AND last_name='GUINESS' ORDER BY title DESC |
+----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0,01 sec)
Już w tym momencie uzyskaliśmy informację na temat czasu, jaki był potrzebny do wykonania zapytania. Przy pomocy profilera jesteśmy w stanie sprawdzić różne, bardzo dokładne i głęboko sięgające dane (w szczególności można się dowiedzieć w jakiej linii kodu i w jakim pliku źródłowym znajduje się funkcja, która realizuje dany etap wykonania zapytania). Dokładny opis tego, co możemy wyciągnąć z profilera znajduje się oczywiście w dokumentacji MySQL – http://dev.mysql.com/doc/refman/5.1/en/show-profiles.html.To, co zazwyczaj wystarcza, to polecenie:
+----------------------+----------+----------+------------+
| Status | Duration | CPU_user | CPU_system |
+----------------------+----------+----------+------------+
| starting | 0.000107 | 0.000000 | 0.000000 |
| Opening tables | 0.000023 | 0.000000 | 0.000000 |
| System lock | 0.000011 | 0.000000 | 0.000000 |
| Table lock | 0.000010 | 0.000000 | 0.000000 |
| init | 0.000073 | 0.000000 | 0.000000 |
| optimizing | 0.000039 | 0.000000 | 0.000000 |
| statistics | 0.000164 | 0.000000 | 0.000000 |
| preparing | 0.000033 | 0.000000 | 0.000000 |
| Creating tmp table | 0.000036 | 0.000000 | 0.000000 |
| executing | 0.000003 | 0.000000 | 0.000000 |
| Copying to tmp table | 0.000609 | 0.000000 | 0.000999 |
| Sorting result | 0.000059 | 0.000000 | 0.000000 |
| Sending data | 0.000036 | 0.000000 | 0.000000 |
| end | 0.000003 | 0.000000 | 0.000000 |
| removing tmp table | 0.000006 | 0.000000 | 0.000000 |
| end | 0.000003 | 0.000000 | 0.000000 |
| query end | 0.000003 | 0.000000 | 0.000000 |
| freeing items | 0.000023 | 0.000000 | 0.000000 |
| logging slow query | 0.000003 | 0.000000 | 0.000000 |
| cleaning up | 0.000003 | 0.000000 | 0.000000 |
+----------------------+----------+----------+------------+
20 rows in set (0,00 sec)
W dwóch pierwszych kolumnach są podane poszczególne etapy wykonywania zapytania i czas, jaki dany etap zajął – otwieranie tabel, zakładanie locka, działanie optimizera, tworzenie tablic tymczasowych, wysyłanie danych, usuwanie tablic tymczasowych i tak dalej. Jest tu dokładnie rozpisane, krok po kroku, operacje, jakie są wykonywane przez MySQL. Kolejne kolumny to w pierwszym zapytaniu czas procesora user i system przeznaczony na poszczególne etapy. Dzięki temu poleceniu można oszacować jakie zapotrzebowanie na zasoby ma dane zapytanie. Można w ten sposób porównać kilka wersji tego samego zapytania z indeksami lub bez. Można porównać kilka różnych zapytań, które zwracają te same wyniki, można oszacować jaki wpływ na wydajność ma np. sortowanie wyników czy agregacja funkcją GROUP BY.
Komentarze