2012-10-17 36 views
0

在下面的查詢中,我顯示銷售的最新狀態(按階段,在這種情況下爲數字3)。查詢是基於在售的狀態歷史記錄的子查詢:優化Mysql:獲取銷售的最新狀態

SELECT v.id_sale, 
IFNULL((
    SELECT (CASE WHEN IFNULL(vec.description, '') = '' 
        THEN ve.name 
        ELSE vec.description 
        END) 
    FROM t_record veh 
    INNER JOIN t_state_campaign vec ON vec.id_state_campaign = veh.id_state_campaign 
    INNER JOIN t_state ve ON ve.id_state = vec.id_state 
    WHERE veh.id_sale = v.id_sale 
    AND vec.id_stage = 3 
    ORDER BY veh.id_record DESC 
    LIMIT 1 
), 'x') sale_state_3 
FROM t_sale v 
INNER JOIN t_quarters sd ON v.id_quarters = sd.id_quarters 
WHERE 1 =1 
AND v.flag =1 
AND v.id_quarters =4 
AND EXISTS (
    SELECT '1' 
    FROM t_record 
    WHERE id_sale = v.id_sale 
    LIMIT 1 
) 

查詢延遲0.0057seg並顯示1011記錄

因爲我必須按照狀態名稱過濾銷售情況,因爲它必須在where子句中重複子查詢,所以我決定使用連接更改相同的查詢。在這種情況下,我使用MAX函數獲取最新狀態:

SELECT 
v.id_sale, 
IFNULL(veh3.State3,'x') AS sale_state_3 
FROM t_sale v 
INNER JOIN t_quarters sd ON v.id_quarters = sd.id_quarters 
LEFT JOIN (
    SELECT veh.id_sale, 
    (CASE WHEN IFNULL(vec.description,'') = '' 
     THEN ve.name 
     ELSE vec.description END) AS State3 
    FROM t_record veh 
    INNER JOIN (
     SELECT id_sale, MAX(id_record) AS max_rating 
       FROM(
        SELECT veh.id_sale, id_record 
        FROM t_record veh 
        INNER JOIN t_state_campaign vec ON vec.id_state_campaign = veh.id_state_campaign AND vec.id_stage = 3 
       ) m 
      GROUP BY id_sale  
    ) x ON x.max_rating = veh.id_record 
    INNER JOIN t_state_campaign vec ON vec.id_state_campaign = veh.id_state_campaign 
    INNER JOIN t_state ve ON ve.id_state = vec.id_state 
) veh3 ON veh3.id_sale = v.id_sale 
WHERE v.flag = 1 
AND v.id_quarters = 4 

此查詢顯示相同的結果(1011)。但問題是它需要0.0753秒

審查的可能性我發現,使得查詢的速度差異的因素:

AND EXISTS (
    SELECT '1' 
    FROM t_record 
    WHERE id_sale = v.id_sale 
    LIMIT 1 
) 

如果我刪除此條款,兩個詢問相同時間延遲...爲什麼它更好?有什麼方法可以在連接中使用這個子句?我希望你的幫助。

編輯

我會告訴解釋每個分別查詢的結果:

Q1: enter image description here

Q2: enter image description here

回答

0

利息ing,這樣基本上判斷t_record.id_sale和t_sale.id_sale是否匹配。

這是什麼讓你的查詢運行速度更快?由於where語句在select語句中的subSelects之前應用,所以如果沒有記錄與銷售一起使用,那麼它不會打擾處理subSelect。這是你的一些時間。所以這就是爲什麼它效果更好。

它會在你的連接語法中工作嗎?我真的不知道沒有你的桌子來測試,但你總是可以把它應用到最後並找出答案。將關鍵字EXPLAIN添加到查詢的開頭,您將得到一個執行計劃,它可以幫助您優化內容。在您的連接語法中獲得更好結果的最好方法可能是向表中添加一些索引。

但我問你,這是否有必要?你有一個查詢返回在<百分之八十秒。除非這個查詢每小時運行幾千次,否則這根本不是真正對您的數據庫徵稅,您的時間可能會更好地用於在應用程序的其他地方進行改進。

+0

感謝您的回覆。對於我來說,這是一個重要的時刻,原因很簡單,我所顯示的查詢只是銷售狀態。他真正的查詢顯示每個階段的不同狀態(每個子查詢/聯接),如果我們添加時間,則有一段時間查詢可能需要1.5秒。對0.3xxx秒。所以知道是否有任何方法來優化連接會很有趣。索引表例如在Table t_record中:i_id_record,i_id_state_campaign,i_id_sale ... – csotelo