Le problème est que MySQL n'utilise qu'un seul index lors de l'exécution de la requête. Si vous ajoutez un nouvel index qui utilise les 3 champs de votre WHERE
clause, il trouvera les lignes plus rapidement.
ALTER TABLE `adverts` ADD INDEX price_status_approved(`price`, `status`, `approved`);
Selon la documentation MySQL ORDER BY Optimization :
C'est ce qui se passe dans votre cas.As la sortie de EXPLAIN
nous dit, l'optimiseur utilise la clé price
pour trouver les lignes. Cependant, le ORDER BY
est sur le champ date_updated
qui n'appartient pas à la clé price
.
Pour trouver les lignes plus rapidement ET trier les lignes plus rapidement, vous devez ajouter un index qui contient tous les champs utilisés dans le WHERE
et dans le ORDER BY
clauses :
ALTER TABLE `adverts` ADD INDEX status_approved_date_updated(`status`, `approved`, `date_updated`);
Le champ utilisé pour le tri doit être en dernière position dans l'index. Il est inutile d'inclure le price
dans l'index, car la condition utilisée dans la requête renverra une plage de valeurs.
Si EXPLAIN
indique toujours qu'il utilise filesort, vous pouvez essayer de forcer MySQL à utiliser un index de votre choix :
SELECT adverts.*
FROM adverts
FORCE INDEX(status_approved_date_updated)
WHERE price >= 0
AND adverts.status = 1
AND adverts.approved = 1
ORDER BY date_updated DESC
LIMIT 19990, 10
Il n'est généralement pas nécessaire de forcer un index, car l'optimiseur MySQL fait le plus souvent le bon choix. Mais parfois, cela fait un mauvais choix, ou pas le meilleur choix. Vous devrez exécuter des tests pour voir si cela améliore ou non les performances.