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

SET PROFILING=1;

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

SHOW PROFILES

sprawdzamy jaki ID zostało przydzielone naszemu zapytaniu.

mysql> show profiles;
+----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 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:

mysql> SHOW PROFILE CPU FOR QUERY 1;

+----------------------+----------+----------+------------+
| 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.