2011-05-30 32 views
2

Explain SQL解釋SQL和查詢優化

解釋說,正在採取超過5秒是給我上面的查詢的SQL(在phpMyAdmin)。我讀到我們可以研究Explain SQL來優化查詢。任何人都可以告訴這個解釋SQL告訴任何事情嗎?

謝謝你們。

編輯:

查詢本身:

SELECT 
a.`depart` , a.user, 
m.civ, m.prenom, m.nom, 
CAST(GROUP_CONCAT(DISTINCT concat(c.id, '~', c.prenom, ' ', c.nom)) AS char) AS coordinateur, 
z.dr 
FROM `0_activite` AS a 
JOIN `0_member` AS m ON a.user = m.id 
LEFT JOIN `0_depart` AS d ON (m.depart = d.depart AND d.rank = 'mod' AND d.user_sec =2) 
LEFT JOIN `0_member` AS c ON d.user_id = c.id 
LEFT JOIN `zone_base` AS z ON m.depart = z.deprt_num 
GROUP BY a.user 

編輯2:兩個表adTable structures

結構。頂部:a和底部:d

編輯3:

我想在此查詢什麼?

我首先想從表中0_activite獲得「走」和「用戶」(這是一個ID)的值。接下來,我想從0_member的ID我從0_activite通過「用戶」獲得人(CIV,prenom和名稱)的名稱,與0_member .ID匹配0_activite。用戶。這裏出發缺少也是身份證的部門。

所以在這一點上,我已經從兩個表0_activite0_member的人離開,身份證,文明,諾姆和prenom。

接下來,我想知道哪個醫生是這個出發有關,這從我得到zone_base。在0_activite0_member中出發的價值相同。

然後是棘手的部分。 0_member中的一個人可以與多個出發點相關聯,並存儲在0_depart中。另外,每個用戶都有一個關卡,其中一個是'mod',代表主持人。現在,我想讓所有在第一位用戶所在位置的主持人都能夠再次獲得0_member的名稱。我也有一個可變的user_sec,但這在這方面可能不那麼重要,儘管我不能忽視它。

這是什麼使查詢一個棘手的一個。 0_member的存儲ID,用戶名,+一個離去,0_depart是存儲用戶的所有的出發,一行每個離去,0_activite存儲着一些其他的東西,我想那些有關通過0_activite,其餘用戶ID。

希望我已經明確。如果我不是,請讓我知道,我會再次嘗試編輯這篇文章。

很多人再次感謝。

+3

在這裏查看查詢也會非常有幫助。 – 2011-05-30 22:23:15

+1

只要你顯示錶結構(包含數據類型)和查詢 – Ibu 2011-05-30 22:34:03

+0

@will A,@,你會得到很好的解釋:) – 2011-05-30 22:49:21

回答

2
從這裏的其他人提供的幾個答案

除了一個關鍵,它可能有助於更好GROUP柱也應該被收錄瞭解查詢中的「我想要什麼」。由於您在另一個問題中接受了我最近的回答,因此您可以使用按部門信息應用的過濾器。

您的查詢是通過rank ='mod'和user_sec = 2在Department表中執行LEFT連接。是否您的總體意圖是顯示0_activite表中的所有記錄,以及0_Depart表的有效連接的無關性......如果與0_Depart表匹配,你只關心'mod'和2個值?

如果你只關心那些具有'mod'和2條件的0_depart特定關聯的人,我將首先顛倒從THIS表開始的查詢,然後加入其餘部分。

通過關係或標準在表上擁有鍵始終是性能優勢(vs沒有索引)。

開始您的查詢與任何將您的最小集FIRST,然後加入到其他表。

從你的問題澄清...我會從最內心開始...它是誰和他們與哪些部門相關...然後獲得主持人(從部門的條件)...然後得到實際主持人的姓名信息...終於出到您zone_base基於主持人的部門的醫生......我

select STRAIGHT_JOIN 
     DeptPerMember.* 
     Moderator.Civ as ModCiv, 
     Moderator.Prenom as ModPrenom, 
     Moderator.Nom as ModNom, 
     z.dr 
    from 
     (select 
       m.ID, 
       m.Depart, 
       m.Civ, 
       m.Prenom, 
       m.Nom 
      from 
       0_Activite as a 
       join 0_member m 
        on a.User = m.ID 
        join 0_Depart as d 
         on m.depart = d.depart ) DeptPerMember 

     join 0_Depart as DeptForMod 
     on DeptPerMember.Depart = DeptForMod.Depart 
     and DeptForMod.rank = 'mod' 
     and DeptForMod.user_sec = 2 

     join 0_Member as Moderator 
      on DeptForMod.user_id = Moderator.ID 

      join zone_base z 
       on Moderator.depart = z.deprt_num 

注意如何tier'd的查詢來獲取每一個部分,並加入到下一個和下一個。我正在根據以前的結果構建鏈,並帶有明確的「別名」參考以澄清內容。現在,您可以通過不同的「別名」引用從任何級別獲取任何相應的元素...

+0

謝謝@DRapp,我非常感謝您的幫助。我試圖通過編輯上面的帖子來解釋我想要的,讓我知道你是怎麼看到的。再次感謝。 – 2011-05-31 21:17:30

+1

@Jeremy Roy,修改幷包含查詢.. – DRapp 2011-05-31 22:19:00

+0

非常感謝@DRapp。是不是這種方法,除非我錯過了一些問題,如:表0_activite列出的東西,活動。現在不是所有的成員都會有活動。我首先獲取0_activite表,以查看哪些用戶有活動,然後獲取有關該用戶的相關信息(如姓名,主持人姓名,博士等)。你在這裏怎麼想?另外,除非我需要,我可以刪除'where m.ID = AnIDIfYouWantOnlyOnePerson',不是嗎? – 2011-05-31 22:24:42

2

EXPLAIN的輸出向我們展示了列出的第一個和第三個表(一個& d)在執行此查詢時沒有任何由數據庫引擎使用的索引。關鍵字列對於兩者都是NULL - 這是一個恥辱,因爲它們都是'大'表(好吧,它們並不是很大,但與其餘表格相比,它們是大的'uns')。

從查詢情況來看,在user0_activite指數和0_depart(depart, rank, user_sec)指數將在一定程度上提高了性能。

+0

謝謝@will A.嗯,這很奇怪,因爲我確實在這些列中有索引。可能我沒有把這些索引放在「正確」的方式?我編輯了原始帖子以添加新圖片。 – 2011-05-31 20:53:44

+1

Jeremy沒問題。你的'0_depart'索引不是'(depart,rank,user_sec)' - 我認爲這個索引值得一試。 – 2011-06-01 01:39:58

+0

你的意思是結合這些3 @ Will的指數? – 2011-06-01 13:42:10

2

您可以看到列keykey_len爲空,這意味着它不使用possible_keys列中的任何鍵。所以表ad都在掃描所有的行。 (在行列中檢查更大的數字,你希望這個更小)。

要處理0_depart: 確保您有一個關鍵字(d.depart, d.rank,d.user_sec),它們是0_depart連接的一部分。

爲了應對0_activite: 我還不能肯定,但因此需要對a.user

+0

謝謝@ weired00。好吧,這很奇怪,因爲我在這些列中有索引。可能我沒有把這些索引放在「正確」的方式?我編輯了原始帖子以添加新圖片。 – 2011-05-31 20:56:52