Je dois optimiser une requête pour un classement qui prend une éternité (la requête elle-même fonctionne, mais je sais que c'est horrible et je viens de l'essayer avec un bon nombre d'enregistrements et ça donne un timeout) .Optimiser la requête de classement lent
Je vais brièvement expliquer le modèle. J'ai 3 tables: joueur, équipe et player_team. J'ai des joueurs, qui peuvent appartenir à une équipe. Aussi évident que cela puisse paraître, les joueurs sont stockés dans la table des joueurs et les équipes en équipe. Dans mon application, chaque joueur peut changer d'équipe à tout moment, et un journal doit être conservé. Cependant, un joueur est considéré comme appartenant à une seule équipe à un moment donné. L'équipe actuelle d'un joueur est la dernière qu'il a rejoint.
La structure du joueur et de l'équipe n'est pas pertinente, je pense. J'ai une colonne d'identification PK dans chaque. Dans player_team j'ai:
id (PK)
player_id (FK -> player.id)
team_id (FK -> team.id)
Maintenant, chaque équipe est assignée un point pour chaque joueur qui s'est joint. Donc, maintenant, je veux obtenir un classement des N premières équipes avec le plus grand nombre de joueurs.
Ma première idée était d'obtenir en premier les joueurs actuels de player_team (c'est-à-dire un record pour chaque joueur, cet enregistrement doit être l'équipe actuelle du joueur). Je n'ai pas réussi à trouver un moyen simple de le faire (essayé GROUP BY player_team.player_id AYANT player_team.id = MAX (player_team.id), mais cela ne l'a pas coupé
J'ai essayé un certain nombre de requêtes que didn ' travail t, mais a réussi à obtenir ce travail.
SELECT
COUNT(*) AS total,
pt.team_id,
p.facebook_uid AS owner_uid,
t.color
FROM
player_team pt
JOIN player p ON (p.id = pt.player_id)
JOIN team t ON (t.id = pt.team_id)
WHERE
pt.id IN (
SELECT max(J.id)
FROM player_team J
GROUP BY J.player_id
)
GROUP BY
pt.team_id
ORDER BY
total DESC
LIMIT 50
Comme je l'ai dit, cela fonctionne, mais semble très mauvais et exécute le pire, donc je suis sûr qu'il doit y avoir une meilleure façon d'aller. tout le monde a des idées pour cette optimisation?
J'utilise MySQL, en passant.
Merci à l'avance
Ajout de l'explication. (Désolé, ne savez pas comment formater correctement)
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t ALL PRIMARY NULL NULL NULL 5000 Using temporary; Using filesort
1 PRIMARY pt ref FKplayer_pt77082,FKplayer_pt265938,new_index FKplayer_pt77082 4 t.id 30 Using where
1 PRIMARY p eq_ref PRIMARY PRIMARY 4 pt.player_id 1
2 DEPENDENT SUBQUERY J index NULL new_index 8 NULL 150000 Using index
Est-ce que vous quittez définitivement toutes les combinaisons d'équipes de joueurs qui se sont déjà produites dans player_team? N'êtes-vous pas en train de le marquer d'une façon ou d'une autre (une colonne qui a 0 pour une relation historique, 1 pour une relation actuelle ferait bien)? – marr75
Oui, je quitte la combinaison puisque je dois tenir un journal. Je pensais avoir un drapeau actuel, et j'irais probablement de l'avant s'il n'y a pas de meilleure alternative. Mais je pense qu'il y a peut-être un meilleur moyen. (Je suis un noob sql!) Merci pour votre suggestion, cependant. –
S'il vous plaît poster votre expliquer. –