2011-05-20 6 views
1

La requête suivante prend 0.1313 secondes sur phpmyadmin. Tout moyen d'optimiser cela pour rendre les choses plus rapides (dites-le en 0.00XX secondes)? Index déjà ajouté aux colonnes qui effectuent les jointures.Optimisation d'une requête mysql complexe

SELECT m.id, m.civ, m.prenom, m.nom, m.sexe, m.depart, m.date_entree, m.date_sortie, m.login_userid, m.login_passwd, a.rank_id, r.rank_m, r.rank_f, d.user_id AS depID, c.nom AS cordo, z.rank 
FROM `0_member` AS m 
LEFT JOIN `0_area` AS a ON (m.id = a.user_id 
AND a.sec_id =2) 
LEFT JOIN `0_rank` AS r ON r.id = a.rank_id 
LEFT JOIN `0_depart` AS d ON (m.depart = d.depart 
AND d.user_sec =2) 
LEFT JOIN `0_area` AS z ON (d.user_id = z.user_id 
AND z.sec_id =2) 
LEFT JOIN `0_member` AS c ON d.user_id = c.id 
WHERE z.rank = 'mod' 
ORDER BY nom 
+1

Y at-il une raison pour laquelle il doit être optimisé pour être plus rapide que 0,00XX secondes? Quelle est la vitesse d'un SELECT standard sur l'une de ces tables? (comme référence) La commande [EXPLAIN] (http://dev.mysql.com/doc/refman/5.5/en/explain.html) peut vous aider à optimiser les requêtes. – Jacob

+0

Regardez, c'est une très mauvaise idée d'utiliser autant de jointures. Cette demande sera toujours un problème pour vous. –

Répondre

1

Votre requête a une dernière clause « where » sur la valeur se trouvant dans la table d'alias « Z » avec un rang de « mod », mais votre requête est tout GAUCHE JOIN indiquant que vous voulez tous les membres quel que soit une correspondance possible sur la table de droite à laquelle vous vous joignez. De plus, vous rejoignez la table "z" en aval en partant et en partant vers un ID utilisateur, puis en rejoignant directement la zone "0_A" comme une table directement sur l'ID de l'utilisateur, ce qui semble être le même comme trouvé de la liaison à la table de départ à la table «z» de toute façon.

Cela dit, et votre membre se joint à partir et à la zone ...

Mon SUGGESTION (et je peux réécrire la requête en tant que telle) est d'inverser l'ordre de la requête de mettre votre table de première zone avec un index sur le "sec_id, rank" étant disponible ... Je voudrais avoir l'ordre de clé basé sur n'importe quelle catégorie ayant la plus petite colonne de sous-ensembles en premier ... donc SEC_ID, RANK ou RANK, SEC_ID. Ensuite faire simple, join (pas LEFT JOIN) aux autres tables ... Au minimum de:

SELECT STRAIGHT_JOIN 
     m.id, 
     m.civ, 
     m.prenom, 
     m.nom, 
     m.sexe, 
     m.depart, 
     m.date_entree, 
     m.date_sortie, 
     m.login_userid, 
     m.login_passwd, 
     a.rank_id, 
     r.rank_m, 
     r.rank_f, 
     d.user_id AS depID, 
     c.nom AS cordo, 
     z.rank 
    FROM 
     `0_area` AS z 
      JOIN `0_depart` AS d 
      on z.user_id = d.user_id 
      and d.user_sec = 2 
      JOIN `0_member` AS m 
       on d.depart = m.depart 
       AND z.user_id = m.id 
      LEFT JOIN `0_rank` AS r 
      on z.rank_id = .rid 
    WHERE 
      z.sec_id = 2 
     AND z.rank = 'mod' 
    ORDER BY 
     nom 

Dans votre requête initiale, vous avez eu une jointure de

member 
    Links to Area (on member's user ID just to ensure the "sec_id = 2") 

Depuis la nouvelle requête cOMMENCE exclusivement avec la table « zone » alias « Z », et que, lorsque la clause est explicitement la valeur « sec_id = 2 », vous aurez jamais besoin de backlink encore ...

Area (only SECID = 2 and rank = mod) 
    Links to Depart (on the User's ID) 
     Links to Members by (on the depart ID) 
+0

Merci @DRapp, je devais 0_area venir deux fois ... comment accueillir cela: | –

+0

@Jeremy Roy, voir la révision pour la clarification pourquoi la jointure supplémentaire n'était pas nécessaire .. (au moins je ne crois pas que ce devrait être) – DRapp

+0

Merci DRAPP. Accepté. :) –

0

Essayez de déplacer ces déclarations "a.sec_id = 2", "d.user_sec = 2", "z.sec_id = 2" des sections ON à la section WHERE comme vous l'avez déjà fait avec "z.rank = 'mod'". Comme ceci:

SELECT m.id, m.civ, m.prenom, m.nom, m.sexe, m.depart, m.date_entree, m.date_sortie, m.login_userid, m.login_passwd, a.rank_id, r.rank_m, r.rank_f, d.user_id AS depID, c.nom AS cordo, z.rank 
FROM `0_member` AS m 
LEFT JOIN `0_area` AS a ON m.id = a.user_id 
LEFT JOIN `0_rank` AS r ON r.id = a.rank_id 
LEFT JOIN `0_depart` AS d ON m.depart = d.depart 
LEFT JOIN `0_area` AS z ON d.user_id = z.user_id 
LEFT JOIN `0_member` AS c ON d.user_id = c.id 
WHERE z.rank = 'mod' 
AND a.sec_id =2 
AND d.user_sec =2 
AND z.sec_id =2 
ORDER BY nom 
+0

non, ne fonctionne pas ... plus ça prend plus de temps –