2016-07-06 71 views
0

我有一個嚴重的問題。我們的內聯網變得越來越慢。其中一個主要原因似乎是一個很慢的mysql查詢(它出現在slow-query.log中)。 每次打開Intranet站點時都會詢問該查詢。 它看起來像這樣:
緩慢MySQL查詢與多個連接,最大()和組由

SELECT w.Datetime, w.User_ID, w.Status, e.Lastname 
FROM worktimes AS w 
INNER JOIN employees AS e ON w.User_ID=e.ID 
RIGHT JOIN (SELECT max(Datetime) AS Datetime, User_ID 
      FROM worktimes 
      WHERE Datetime>".$today." // variable of today 0.00 o'clock 
      AND Location='".$llocation['ID']."' // variable of one of 9 locations 
      GROUP BY User_ID) AS v 
     ON v.User_ID=w.User_ID AND w.Datetime=v.Datetime 
ORDER BY e.Lastname; 

的worktimes表是高達20萬行(瞬時90K到測試的原因)和13列稍大。整個查詢經歷3到9個循環的循環。

有人想法如何使查詢更快?

編輯:這裏是希望解釋結果。

id select_type  table  type possible_keys key  key_len ref    rows Extra 
1 PRIMARY   <derived2> ALL  NULL   NULL  NULL  NULL    44006 Using temporary; Using filesort 
1 PRIMARY   w   ALL  NULL   NULL  NULL  NULL    92378 Using where 
1 PRIMARY   e   eq_ref PRIMARY,ID  PRIMARY 4  ais_v1.w.User_ID  1 NULL 
2 DERIVED   worktimes ref  Location  Location 767  const    44006 Using index condition; Using where; Using temporary; Using filesort 
+3

你可以做查詢的'EXPLAIN SELECT'嗎? – Daan

+0

您的意思是更多細節?好的,我會更新這個問題。 –

+0

不,我的意思是用前面的'EXPLAIN'執行確切的查詢,並在這裏發佈結果。 – Daan

回答

0

w表需要的索引INDEX(Location, Datetime)。這應該會改善性能。

+0

你可以在查詢中設置索引嗎?或者我應該更改數據庫表並將索引設置爲字段位置和日期時間? –

+0

我更改了數據庫表並將索引設置爲字段位置和日期時間。數據庫本身是使用它還是必須在查詢中包含它的名字? –

+0

索引的名稱僅用於執行DROP INDEX。你什麼都不做;該查詢應該自動使用索引。 –

0

你不需要使用worktimes兩次

你可以按如下做到這一點:

SELECT max(w.Datetime) AS Datetime, w.User_ID, w.User_ID, w.Status, e.Lastname 
     FROM worktimes w left outer join employees e 
     on e.User_ID=w.User_ID 
     and w.Datetime>".$today." // variable of today 0.00 o'clock 
    AND w.Location='".$llocation['ID']."' // variable of one of 9 locations 
     GROUP BY w.User_ID 
     ORDER BY e.Lastname; 

它會運行速度比現有查詢

+0

Erm ...如果殺死子查詢「AS v」,則不再有任何可能使用v.User_ID或v.Datetime;) –

+0

如果以這種方式更改查詢,則不會獲得工作時間中的最後一個條目,但結果是隨機的。這就是我製作這個複雜子查詢的原因。 –

+0

在這種情況下,您可以使用臨時表在其中存儲此查詢的輸出,並使用手動查詢的觸發器將數據插入到此臨時表中,因爲它插入到主表中 –