2011-08-15 60 views
2

我在優化MySQL查詢時遇到了實際困難。我必須使用現有的數據庫結構,但在某些情況下,我的響應速度非常慢。如何優化我的MySQL查詢?

我的查詢是:

SELECT 
    `t`.*, 
    `p`.`trp_name`, 
    `p`.`trp_lname`, 
    `trv`.`trv_prosceslevel`, 
    `trv`.`trv_id`, 
    `v`.`visa_destcountry`, 
    `track`.`track_id`, 
    `track`.`track_datetoembassy`, 
    `track`.`track_expectedreturn`, 
    `track`.`track_status`, 
    `track`.`track_comments` 
FROM 
    (SELECT 
     * 
    FROM 
     `_transactions` 
    WHERE 
     DATE(`tr_datecreated`) BETWEEN DATE('2011-07-01 00:00:00') AND DATE('2011-08-01 23:59:59')) `t` 
     JOIN 
    `_trpeople` `p` ON `t`.`tr_id` = `p`.`trp_trid` AND `p`.`trp_name` = 'Joe' AND `p`.`trp_lname` = 'Bloggs' 
     JOIN 
    `_trvisas` `trv` ON `t`.`tr_id` = `trv`.`trv_trid` 
     JOIN 
    `_visas` `v` ON `trv`.`trv_visaid` = `v`.`visa_code` 
     JOIN 
    `_trtracking` `track` ON `track`.`track_trid` = `t`.`tr_id` AND `p`.`trp_id` = `track`.`track_trpid` AND `trv`.`trv_id` = `track`.`track_trvid` AND `track`.`track_status` IN ('New','Missing_Info', 
     'En_Route', 
     'Ready_Pickup', 
     'Received', 
     'Awaiting_Voucher', 
     'Sent_Client', 
     'Closed') 
ORDER BY `tr_id` DESC 

的結果對上述解釋的說法是:直到「封閉」的值被包含在非常

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 PRIMARY  <derived2> ALL  NULL NULL NULL NULL 164  Using temporary; Using filesort 

1 PRIMARY  track ALL  status_index NULL NULL NULL 4677 Using where 

1 PRIMARY  p eq_ref PRIMARY  PRIMARY  4 db.track.track_trpid 1 Using where 

1 PRIMARY  trv  eq_ref PRIMARY  PRIMARY  4 db.track.track_trvid 1 Using where 

1 PRIMARY  v eq_ref visa_code visa_code 4 db.trv.trv_visaid 1 

2 DERIVED  _transactions ALL  NULL NULL NULL NULL 4276 Using where 

查詢時間是可以接受的最後track.track_status IN條款。時間長度然後增加約10至15倍的其他查詢。

這很有意義,因爲'封閉'狀態是指所有交易已處理的客戶,相當於數據庫的約90%到95%。

問題是,在某些情況下,搜索大約需要45秒,這是可笑的。我敢肯定,MySQL可以做的比這更好,這只是我的錯誤查詢,即使這些表有4000行,但我無法弄清楚如何優化這個語句。

我很感激一些關於我要出錯的建議,以及我應該如何實現這個查詢來產生更快的結果。

非常感謝

+1

首先,你不需要't'子查詢,只要把它到主查詢這樣'FROM _transactions的... WHERE DATE (...)之間...' –

回答

1

試試這個:

SELECT t.*, 
p.trp_name, 
p.trp_lname, 
trv.trv_prosceslevel, 
trv.trv_id, 
v.visa_destcountry, 
track.track_id, 
track.track_datetoembassy, 
track.track_expectedreturn, 
track.track_status, 
track.track_comments 
FROM 

_transactions t 
JOIN _trpeople p ON t.tr_id = p.trp_trid 
JOIN _trvisas trv ON t.tr_id = trv.trv_trid 
JOIN _visas v ON trv.trv_visaid = v.visa_code 
JOIN _trtracking track ON track.track_trid = t.tr_id 
AND p.trp_id = track.track_trpid 
AND trv.trv_id = track.track_trvid 
WHERE DATE(t.tr_datecreated) 
    BETWEEN DATE('2011-07-01 00:00:00') AND DATE('2011-08-01 23:59:59') 

    AND track.track_status IN ('New','Missing_Info','En_Route','Ready_Pickup','Received','Awaiting_Voucher','Sent_Client', 'Closed') 
    AND p.trp_name = 'Joe' AND p.trp_lname = 'Bloggs' 
ORDER BY tr_id DESC 
+0

我不得不說這太了不起了。這對我來說現在在0.2秒內執行。你能說我做錯了嗎?你已經刪除了子查詢,並把所有的條件查詢放在最後。我認爲我的子查詢將首先縮小搜索結果的範圍,以便減少連接的輸入大小。不正確,顯然。 – Joe

+1

你是對的。在執行主查詢之前,您引入的子查詢消耗了大量時間。 – reggie

+0

感謝您的評論。我仍然不確定子查詢爲什麼會這麼慢。我在網上閱讀過很多人推薦遠離子查詢,只使用連接。你會推薦這種方法嗎? – Joe