2012-04-13 3 views
-1
SELECT u.id, u.honour, COUNT(*) + 1 AS rank 
FROM user_info u 
INNER JOIN user_info u2 
    ON u.honour < u2.honour 
WHERE u.id = '$id' 
    AND u2.status = 'Alive' 
    AND u2.rank != '14' 

Cette requête ralentit actuellement complètement mon serveur. Cela fonctionne en fonction de votre honneur quel rang vous êtes dans la table 'user_info' qui le stocke sur tous nos utilisateurs.Optimiser et améliorer les performances de cette requête MYSQL

Capture d'écran de explain.

http://cl.ly/370z0v2Y3v2X1t1r1k2A

SELECT u.id, u.honour, COUNT(*)+1 as rank 
FROM user_info u 
    USE INDEX (prestigeOptimiser) 
INNER JOIN user_info u2 
    ON u.honour < u2.honour 
WHERE u.id='3' 
    AND u2.status='Alive' 
    AND u2.rank!='14' 
+1

Vous avez probablement besoin d'ajouter quelques index –

+0

Avez-vous remarqué que vous n'avez aucun groupe? –

+0

pouvez-vous inclure une explication étendue de votre choix – ManseUK

Répondre

1

Je pense que la charge provient de la condition de jointure '<'.

Vous pouvez essayer de fractionner votre requête ou (ou si vous préférez une sous-requête) et utiliser l'index d'honneur pour le nombre.

SELECT id, honour INTO @uid, @uhonour 
FROM user_info 
WHERE id = '$id'; 

SELECT @uid, @uhonour, COUNT(honour) + 1 as rank 
FROM user_info 
WHERE status = 'Alive' 
AND rank != '14' 
AND @uhonour < honour; 
1

Tout d'abord, vous devez ajouter une clause group by afin que votre requête est logique. Deuxièmement, vous devez modifier la colonne d'état pour contenir un entier pour réduire l'indice.

Troisièmement, vous devez créer un index sur id et le statut comme celui-ci:

alter table user_info add index idxID_Status (id, status) 

Enfin, pour obtenir les rangs vous devriez jeter un oeil à ce answer. De plus, vous devriez ajouter un moyen de les commander ... obtenir un rang sans ordre n'est pas vraiment un rang.

+0

Pourquoi pensez-vous que la requête n'a pas de sens? Remarquez qu'il y a 'WHERE u.id = '$ id'', donc c'est seulement un utilisateur, donc un groupe. –

+0

@Shedal Avez-vous remarqué qu'il n'y a pas de groupe par et Y a-t-il une fonction d'agrégation? –

+0

Oui, je l'ai fait. Essayez-le sur une simple requête. Compter toutes les lignes sélectionnées fait exactement ce que David essaie de réaliser dans ce cas. –

1

Comme nous pouvons le voir d'expliquer, MySQL utilise le mauvais index ici. Pour commencer, il suffit de supprimer tous les index et en créer un nouveau, contenant au moins ces deux champs: Id et Honour. Cela devrait considérablement augmenter les performances.

ALTER TABLE user_info ADD INDEX myIndex (id, honour); 
+0

Comment cela affecterait-il le reste du site qui dépend des autres index? Puis-je avoir un index groupé et un index unique? – David

+0

Oh, d'accord, mon conseil était un peu pressé, je voulais juste dire que c'était une expérience. Ensuite, créez simplement ce nouvel index, ne laissez rien tomber. Mais alors vous devrez peut-être suggérer à MySQL d'utiliser le bon index. –

+0

Comment ferais-je cela? – David

Questions connexes