优化复杂的mysql查询

时间:2011-05-20 11:29:59

标签: php mysql join phpmyadmin

以下查询在phpmyadmin上占用0.1313秒。有什么方法可以优化它以使事情变得更快(比如想要在0.00XX秒内获得它)?已经在正在进行加入的列中添加了索引。

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

2 个答案:

答案 0 :(得分:1)

您的查询在“Z”别名表中的值为FOUND的最后一个“WHERE”子句,其等级为“mod”,但您的查询都是LEFT JOIN,表示您希望所有成员无论可能匹配你要加入的右边桌子。

此外,您通过离开并离开用户ID加入下游到“z”表,然后直接重新加入“0_area”作为A表直接在用户ID上显示它将与无论如何,从链接到离开表到'z'表找到。

那就是说,你的成员加入离开然后去了地区......

我的建议(我可以这样重写查询)是颠倒查询的顺序,将您的Area表FIRST与索引放在“sec_id,rank”可用...我将基于密钥顺序在哪个类别中,较小的子列列首先...所以SEC_ID,RANK或RANK,SEC_ID。 然后对其他表做简单的JOIN(而不是LEFT JOIN)...至少从:

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

在原始查询中,您有来自

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

由于新查询仅使用“area”表作为“Z”别名进行STARTING,并且THAT where子句明确为“sec_id = 2”值,因此您永远不需要再次反向链接...

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

答案 1 :(得分:0)

尝试将此语句“a.sec_id = 2”,“d.user_sec = 2”,“z.sec_id = 2”从ON部分移动到WHERE部分,就像您已使用“z.rank ='mod'”一样。像这样:

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