Une page lente, c'est d'ordinaire une requête lente et non un serveur lent. MySQL vous dira laquelle si vous le lui demandez, et la question coûte un réglage.

L'activer

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

Une seconde est un bon seuil de départ : il attrape ce qui compte sans remplir le disque. Rendez-le permanent dans my.cnf une fois que vous savez qu'il sert.

Le lire

mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

Cela trie par temps total et imprime les dix pires. Une requête qui prend 0,2 s mais tourne trois cents fois par page est pire qu'une qui prend 2 s une seule fois, et ce classement le montre.

Demander pourquoi elle est lente

EXPLAIN SELECT ... ;
  • type: ALL - un parcours complet de la table. Chaque ligne lue pour répondre à une seule question.
  • rows : un grand nombre - combien de lignes elle s'attend à lire. Comparez-le au nombre que vous attendez en retour.
  • Using filesort - un tri en mémoire ou sur disque, parce qu'aucun index ne donne l'ordre voulu.

L'index qui règle d'ordinaire l'affaire

Un index sur la colonne de la clause WHERE. Si la requête filtre sur deux colonnes, un seul index sur les deux, dans l'ordre où la requête les utilise.

CREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at);
Un index n'est pas gratuit : il ralentit les écritures et prend de la place. Ajoutez celui que le journal a désigné, puis mesurez de nouveau. Mettre un index sur chaque colonne, c'est ainsi qu'une base devient plus lente.
Relancez EXPLAIN après l'avoir ajouté. Si type vaut toujours ALL, l'index n'est pas utilisé - d'ordinaire parce que la requête enveloppe la colonne dans une fonction, et aucun index n'y peut rien.