简体   繁体   English

优化复杂的mysql查询

[英]Optimizing a complex mysql query

The following query is taking 0.1313 seconds on phpmyadmin. 以下查询在phpmyadmin上花费0.1313秒。 Any way to optimize this to make things faster (say like to get it in 0.00XX seconds)? 有什么方法可以优化它,从而使事情更快(比如说在0.00XX秒内得到它)? Index already added at columns that are doing the joinings. 已经在进行联接的列上添加了索引。

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

Your query has a final "WHERE" clause on the value being FOUND in the "Z" alias table with a rank of 'mod', yet your query is all LEFT JOINs indicating you want all members regardless of a possible match on the right side table you are joining to. 您的查询在别名为“ Z”的“ Z”别名表中的FOUND值上具有最终的“ WHERE”子句,但查询为所有LEFT JOIN,表示您希望所有成员,无论右侧是否可能匹配您要加入的表。

Additionally, you are joining downstream to the "z" table by depart and depart to a user ID, then re-joining directly to the '0_area' as A table directly on the user's ID which APPEARS it would be the same as found from the linking to the depart table to the 'z' table anyhow. 此外,您通过离开并离开用户ID来下游连接到“ z”表,然后直接作为用户ID上的A表直接重新连接到“ 0_area”,这看起来与从用户ID中找到的相同无论如何,将离开表链接到“ z”表。

That said, and your member joins to depart and then to area... 也就是说,您的成员加入后出发,然后前往该地区...

My SUGGESTION (and I can rewrite the query as such) is to reverse the order of the query putting your Area table FIRST with an index on the "sec_id, rank" being available... I would have the key order based on whichever category had the smaller subset column first... so either SEC_ID, RANK or RANK, SEC_ID. 我的建议(并且我可以这样重写查询)是颠倒查询的顺序,将您的Area表放在FIRST上,并在“ sec_id,rank”上建立索引...我将根据任何类别获得关键顺序首先具有较小的子集列...因此是SEC_ID,RANK或RANK,SEC_ID。 Then doing simple JOIN (not LEFT JOIN) to the other tables... At a minimum from: 然后对其他表进行简单的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

In your original query, you had a join from 在原始查询中,您来自

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

Since the new query is exclusively STARTING with the "area" table as "Z" alias, and THAT where clause is explicitly "sec_id = 2" value, you'll never need to backlink again... 由于新查询专门以“ area”表作为“ Z”别名开头,并且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)

Try moving this statements " a.sec_id =2 ", "d.user_sec =2 ", " z.sec_id =2 " from ON sections to WHERE section like you already did with "z.rank = 'mod'". 像使用“ z.rank ='mod'”一样,尝试将此语句“ a.sec_id = 2”,“ d.user_sec = 2”,“ z.sec_id = 2”从ON部分移动到WHERE部分。 Like this: 像这样:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM