Des conseils pour l'amélioration de cette lenteur de la requête mysql?
Je suis en utilisant une requête qui, généralement, s'exécute en moins d'une seconde, mais parfois cela prend entre 10 et 40 secondes pour terminer. En fait, je suis pas totalement clair sur la façon dont la sous-requête fonctionne, je sais juste qu'il travaille, qu'il me donne 15 lignes pour chaque faverprofileid.
Je suis la journalisation des requêtes lentes et il me dit 5823244 lignes ont été examinés, ce qui est bizarre, parce qu'il n'y a pas n'importe où près que le nombre de lignes dans les tables concernées (le tableau de favoris a plus de 50 000 lignes).
Quelqu'un peut-il m'offrir quelques conseils? Est-il un problème avec la sous-requête et avoir besoin d'utiliser filesort?
EDIT: Exécution d'expliquer montre que la table des utilisateurs n'est pas à l'aide d'un indice (même si id est la clé primaire). En vertu de l'extra il dit: à l'Aide temporaire; à l'Aide de filesort.
SELECT F.id,F.created,U.username,U.fullname,U.id,I.*
FROM favorites AS F
INNER JOIN users AS U ON F.faver_profile_id = U.id
INNER JOIN items AS I ON F.notice_id = I.id
WHERE faver_profile_id IN (360,379,95,315,278,1)
AND F.removed = 0
AND I.removed = 0
AND F.collection_id is null
AND I.nudity = 0
AND (SELECT COUNT(*) FROM favorites WHERE faver_profile_id = F.faver_profile_id
AND created > F.created AND removed = 0 AND collection_id is null) < 15
ORDER BY F.faver_profile_id, F.created DESC;
Êtes-vous essayer de sélectionner les 15 premiers éléments pour chaque faver_profile_id commandé par créé?
Avez-vous analyse sur les tables?
La table des utilisateurs n'était pas à l'aide d'un index et les favoris de l'été à l'aide de la "suppression" de l'index au lieu de faver_profile_id. Pour certains, la raison de la suppression de la "suppression" de l'index (que je n'ai pas vraiment besoin) fixe ces deux questions. J'ai aussi opté pour des GROUP BY et HAVING et la requête fonctionne maintenant très rapide. Merci!
OriginalL'auteur makeee | 2009-02-26
Vous devez vous connecter pour publier un commentaire.
Je pense qu'avec
GROUP BY
etHAVING
il devrait être plus rapide.Est-ce que vous voulez?
Ne sais pas quels champs de
items
vous avez besoin, alors j'ai mis des espaces réservés.OriginalL'auteur vartec
Le nombre de lignes examiné représente est grand car beaucoup de lignes ont été examinés plus d'une fois. Vous obtenez ce à cause de mal optimisé plan de requête qui résultats dans les analyses de la table lors de la recherche d'index doit avoir été effectuée. Dans ce cas, le nombre de lignes examiné est exponentielle, c'est à dire d'un ordre de grandeur comparable au produit du nombre total de lignes dans plus d'une table.
Vous pouvez également modifier votre requête à utiliser
GROUP BY faver_profile_id
/HAVING count > 15
au lieu de la imbriquéeSELECT COUNT(*)
sous-requête, comme suggéré parvartec
. La performance de votre origine et devartec
's de la requête doivent être comparables si les deux sont correctement optimisés par exemple à l'aide d'indicateurs (votre requête imbriquer la recherche d'index, alors quevartec
'requête serait d'utiliser un hachage de stratégie.)OriginalL'auteur vladr
Je vous suggère d'utiliser Mysql Expliquer Requête pour voir comment votre serveur mysql gère la requête. Mon pari est de votre index n'est pas optimale, mais d'en expliquer devrait faire beaucoup mieux que mon pari.
OriginalL'auteur Yuval F
Que vous pourriez faire une boucle sur chaque id et limite d'utilisation au lieu de count(*) sous-requête:
OriginalL'auteur
Je vais supposons que le résultat de cette requête est destiné à être montré comme une liste paginée. Dans ce cas, vous pourriez peut-être envisager de faire un simple "non" interrogation et de faire une deuxième requête pour chaque ligne pour lire uniquement les 15, 20 ou 30 éléments. N'était pas ADHÉRER à une lourde opération? Cela permettrait de simplifier la requête et Il ne serait pas devenu plus lent lorsque les tables jointes croître.
Dites-moi si je me trompe, s'il vous plaît.
OriginalL'auteur