Vous avez demandé " pourquoi cela prend trop de temps ?". Vous avez également dit " Malheureusement, cela a pris plus de 5 secondes pour récupérer les données et me les montrer ". Vous avez également signalé la sortie de profilage de votre requête.
Comme vous pouvez le constater vous-même, la somme des temps rapportés par le profileur pour chaque étape compte pour 0,000154 secondes. Du point de vue du profileur, la requête s'est donc terminée dans un tel délai (0.000154).
Alors pourquoi obtenez-vous des résultats en " ... plus de 5 secondes? ".
Vous avez dit que vous filtriez une table d'enregistrement de 23 millions avec un champ de 3 caractères. Malheureusement, vous ne nous dites pas combien d'enregistrements votre requête renvoie ... mais grâce au EXPLAIN SELECT fourni, il semble que votre requête ait renvoyé 336052 enregistrements.
Il semble également que toute votre activité passe par une interface graphique (PHPMyAdmin?).
Donc, après tout ce qui précède, nous pouvons reformuler votre question initiale comme suit:
"Pourquoi est-ce que j'obtiens, dans mon interface graphique, 336.052 enregistrements affichés en plus de 5 secondes, si le temps d'exécution MySQL pour la requête associée est de 0.000154 secondes?"
La réponse, à mon avis, est assez simple: 5 secondes est le temps (vraiment bas, en effet) pour laisser 336.052 enregistrements se déplacer le long du chemin: moteur MySQL => bibliothèques client MySQL => module PHP MySQL => Apache => réseau = > votre pile TCP / IP PC => Navigateur => Analyseur DOM / constructeur / etc. => Page HTML rendue.
Quant à mon expérience précédente, le temps requis par la transmission des résultats est "normalement" beaucoup plus élevé que le temps nécessaire pour récupérer ces données. Cela est particulièrement vrai lorsque des bibliothèques comme PHP-MySQL ou Perl-DBD-MySQL sont impliquées: elles nécessitent vraiment beaucoup de temps pour récupérer les enregistrements, après que MySQL les a correctement identifiés (... et extraits).
Comment résoudre ce problème?
Encore une fois, assez facilement: êtes-vous vraiment sûr d'avoir besoin de TOUS les enregistrements 336.052, dans un seul ensemble de données?
Si votre réponse est vraiment "OUI! J'ai besoin de tous", votre application gérera PAGINATION et / ou USER-Interaction par elle-même et ... une fois qu'elle aura rassemblé toutes ces données, elle passera probablement beaucoup de temps. interagir avec l'utilisateur sans nécessiter d'autre interaction MySQL. Dans un tel cas, attendre 5 secondes (voire plus) ne devrait pas être un problème;
Si votre réponse est "NON, je veux gérer une taille de jeu de données plus" humaine "", vous devez affiner votre requête (au moins) afin qu'elle vous redonne un jeu de données plus "humain" (des dizaines ou, des centaines, tout au plus, des enregistrements). Dans un tel cas, je parie que vous obtiendrez votre résultat dans un temps plus court.
BTW: c'est exactement le même problème que vous avez rencontré dans cet autre article , à ServerFault: 88 secondes pour laisser 132 millions d'enregistrements se déplacer le long du chemin magique .... pas-mysql-strictement lié :-)