Comment optimiser cette requête MySQL faible performance?
-
01-10-2019 - |
Question
J'utilise actuellement la requête suivante pour jsPerf. Dans le cas probable que vous ne connaissez pas jsPerf - il y a deux tables: pages
contenant les cas de test / révisions et tests
contenant les extraits de code pour les tests à l'intérieur des cas de test
Il y a actuellement 937 enregistrements dans pages
et 3817 enregistrements tests
.
Comme vous pouvez le voir, il faut un certain temps pour charger la page « Parcourir jsPerf » où cette requête est utilisé.
La requête prend environ 7 secondes pour exécuter:
SELECT
id AS pID,
slug AS url,
revision,
title,
published,
updated,
(
SELECT COUNT(*)
FROM pages
WHERE slug = url
AND visible = "y"
) AS revisionCount,
(
SELECT COUNT(*)
FROM tests
WHERE pageID = pID
) AS testCount
FROM pages
WHERE updated IN (
SELECT MAX(updated)
FROM pages
WHERE visible = "y"
GROUP BY slug
)
AND visible = "y"
ORDER BY updated DESC
J'ai ajouté des index sur tous les champs qui apparaissent dans les clauses de WHERE
. Dois-je ajouter?
Comment cette requête optimisée?
P.S. Je sais que je pourrais mettre en œuvre un système de mise en cache en PHP -. Je vais probablement, alors s'il vous plaît ne me dites pas :) Je voudrais juste vraiment savoir comment cette requête pourrait être améliorée, aussi
La solution
Utilisation:
SELECT x.id AS pID,
x.slug AS url,
x.revision,
x.title,
x.published,
x.updated,
y.revisionCount,
COALESCE(z.testCount, 0) AS testCount
FROM pages x
JOIN (SELECT p.slug,
MAX(p.updated) AS max_updated,
COUNT(*) AS revisionCount
FROM pages p
WHERE p.visible = 'y'
GROUP BY p.slug) y ON y.slug = x.slug
AND y.max_updated = x.updated
LEFT JOIN (SELECT t.pageid,
COUNT(*) AS testCount
FROM tests t
GROUP BY t.pageid) z ON z.pageid = x.id
ORDER BY updated DESC
Autres conseils
Vous voulez apprendre comment utiliser EXPLAIN. Cela exécutera l'instruction SQL, et vous montrer quels index sont utilisés, et ce que les analyses sont en cours d'exécution ligne. L'objectif est de réduire le nombre de balayages de ligne (c.-à la base de données de recherche ligne par ligne pour les valeurs).
Vous pouvez essayer les sous-requêtes une à la fois pour voir lequel est le plus lent.
Cette requête:
SELECT MAX(updated)
FROM pages
WHERE visible = "y"
GROUP BY slug
Permet de trier le résultat par limaces. Ceci est probablement lent.