2013-04-06 147 views
0

所以我在這裏有一個基本的查詢選擇日期範圍。它似乎需要(相對較長的時間來處理)我想知道我能做些什麼來改善處理時間。這是查詢。加速mysql查詢

SELECT h.id as hid,h.created_on,u.id as uid,u.fname,u.lname,u.email 
FROM hud h 
LEFT JOIN user_hud uh on h.id = uh.hid 
LEFT JOIN users u on u.id = uh.uid 
WHERE 
    h.created_on 
    BETWEEN DATE_SUB(CURDATE() ,INTERVAL 12 MONTH) 
     AND DATE_SUB(CURDATE() ,INTERVAL 7 DAY) 
+0

打破了查詢是允許的。 – GolezTrol 2013-04-06 18:05:43

+0

'解釋',任何人? – raina77ow 2013-04-06 18:07:05

+1

你在'''hud.id''','''user_hud.hid''','users.id''','user_hud.uid''和'''hud .created_on'''列?發佈查詢的「EXPLAIN」(http://dev.mysql.com/doc/refman/5.5/en/explain.html)。返回多少行,處理時間是多少? – dtech 2013-04-06 18:07:19

回答

1

hud.iduser_hud.hidusers.iduser_hud.uidhud.created_on列製作的索引。

沒有索引需要檢查整個表的加入。使用索引,您可以使用更高效的方法(以更新/刪除性能損失和更多磁盤空間爲代價)

0

首先,您至少需要以下索引:hud中的(created_on),user_hud中的(hid)。然後,你可以看看你的查詢,並意識到你的條件是在第一個表中您的加入,讓你可以移動到條件的子查詢:

SELECT hids.*, u.id as uid, u.fname, 
      u.lname, u.email 
FROM (
    SELECT id as hid, created_on 
    FROM hud, 
     (SELECT DATE_SUB(CURDATE() ,INTERVAL 12 MONTH) as year_ago, 
        DATE_SUB(CURDATE() ,INTERVAL 7 DAY) as week_ago) d 
    WHERE created_on BETWEEN year_ago AND week_ago 
    ) as hids 
LEFT JOIN user_hud uh USING(hid) 
LEFT JOIN users u on u.id = uh.uid; 
+0

這個條件是在'''hud'''上,所以優化器應該只從hud獲得符合條件的記錄,所以我認爲這是不必要的。但是解釋是唯一可以確定的方法。另外:現在在'''FROM'''裏沒有2個表嗎?我想你的意思是隻從子查詢中選擇。 – dtech 2013-04-06 18:49:16

+0

@dtech,不幸的是,優化器不夠好,但是你說得對,解釋可能會說明問題。子查詢中有兩個表,但這應該沒有問題,第二個只執行一次。 – newtover 2013-04-06 19:03:45