2011-05-20 121 views
1

以下查詢在phpmyadmin上執行時間爲0.1313秒。任何方式來優化這個讓事情變得更快(比如說在0.00XX秒內)?索引已添加到正在進行連接的列中。優化複雜的mysql查詢

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

是否有一個原因需要優化,以便快於0.00XX秒?其中一個表上的標準SELECT有多快? (作爲基線)[EXPLAIN](http://dev.mysql.com/doc/refman/5.5/en/explain.html)命令可以幫助您優化查詢。 – Jacob 2011-05-20 11:33:05

+0

看,使用這麼多連接是一個非常糟糕的主意。這一要求對你來說總是一個問題。 – 2011-05-20 12:03:54

回答

1

您所查詢的對價值的最終「WHERE」子句中的「Z」別名表被發現「國防部」的排名,但是你的查詢是所有LEFT JOIN的表示要不顧一切成員可能會匹配您要加入的右側桌面。

此外,您將通過啓動並跳轉到用戶標識,然後直接重新連接到'0_area'作爲表,直接在用戶的ID上顯示它將是相同的無論如何,從鏈接到分離表到'z'表中找到。

這就是說,你的成員加入出發,然後到區...

我的建議(我可以重寫查詢本身)是扭轉查詢的順序把您的區域表先用一個關於「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") 

一個加入,因爲新的查詢專門的「區域」表作爲「Z」的別名開始,並且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) 
+0

謝謝@DRapp,我有0_area來了兩次......如何包容: – 2011-05-20 14:10:17

+0

@Jeremy Roy,請參閱修訂以澄清爲什麼不需要額外連接..(至少我不相信它應該是) – DRapp 2011-05-20 14:22:04

+0

謝謝DRAPP。公認。 :) – 2011-05-25 11:17:50

0

嘗試移動此聲明「ON.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 
+0

nope,不工作...加上它需要更長的時間 – 2011-05-20 14:15:40