2013-06-03 107 views
0

我所試圖做的是創造100個查詢 將做以下檢查:以兩個SQL查詢到一個查詢工作太慢

我已經得到了無論是在「yesnotmp」數據庫​​2個表。 一個叫做msg_t它包含了所有的消息,它有很多的列。我在意的是這兩個查詢中的那兩個是send_timestatus,phone,sushi_sub_id

在這裏,我得到了昨天的所有電話,sushi_sub_id記錄。 (和它的作品)

SELECT phone, sushi_sub_id FROM `yesnotmp`.`msg` 
     LEFT JOIN `yesnotmp`.`msg_t` ON (`msg`.`id`=`msg_t`.`msg_id`) 
     WHERE `msg_t`.`send_time` BETWEEN '2013-06-02' AND '2013-06-03' 
      AND `msg_t`.`status` = 'Failure.Provider.Connection' 

我所試圖做的是去檢查retry表多少phone插入具有相同sushi_sub_id多少不是。 (此查詢需要很長時間)

SELECT 
    Sum(CASE WHEN (SELECT Count(*) FROM `retry` AS `rty` WHERE `rty`.`phone` = `msgs`.`phone` AND `rty`.`sushi_subscription_id`=`msgs`.`sushi_sub_id`) > 0 THEN 1 ELSE 0 END) AS `In_Retry`, 
Sum(CASE WHEN (SELECT Count(*) FROM `retry` AS `rty` WHERE `rty`.`phone` = `msgs`.`phone` AND `rty`.`sushi_subscription_id`=`msgs`.`sushi_sub_id`) > 0 THEN 0 ELSE 1 END) AS `Not_In_Retry` 
FROM 
    (SELECT phone, sushi_sub_id FROM `yesnotmp`.`msg` 
     LEFT JOIN `yesnotmp`.`msg_t` ON (`msg`.`id`=`msg_t`.`msg_id`) 
     WHERE `msg_t`.`send_time` BETWEEN '2013-06-02' AND '2013-06-03' 
      AND `msg_t`.`status` = 'Failure.Provider.Connection') AS `msgs` 
+0

你說'它有效',但是WHERE子句有效地將你的LEFT [outer] JOIN作爲[inner] JOIN進行渲染,所以你不妨寫下它以開始... SELECT m.phone , m.sushi_sub_id 味精米 JOIN msg_t噸 ON t.msg_id = m.id WHERE t.send_time BETWEEN '2013年6月2日' 與 '2013年6月3日' AND t.status =「失效。 Provider.Connection「; – Strawberry

回答

3

輕微的改動,我建議......不要通過選擇總結爲每列,但簡單連接,直接計數。首先,你的LEFT-JOIN到Msg_T表,但是在Msg_T表上有一個WHERE子句強制它成爲一個INNER JOIN。

您正在查找給定日期和狀態之間的消息時間活動。爲了幫助優化查詢,我將在MSG_T on(status,send_time)上有一個索引,以便它可以直接跳轉到您的「Failure.Provider.Connection」,然後直接跳轉到有問題的日期範圍。

現在,重試表。這可以是一個左連接,因爲你可能永遠不會有重試條目(糾正我,如果我錯了)。

SELECT 
     msg_t.phone, 
     msg_t.sushi_sub_id, 
     max(case when rty.phone is not null then 1 else 0 end) as In_Retry, 
     max(case when rty.phone is null then 1 else 0 end) as Not_In_Retry 
    FROM 
     yesnotmp.msg_t msg_t 
     JOIN yesnotmp.msg msg 
      ON msg_t.msg_id = msg.id 
      LEFT JOIN `retry` rty 
       ON msg_t.phone = rty.phone 
       AND msg_t.sushi_sub_id = rty.sushi_subscription_id 
    WHERE 
      msg_t.status = 'Failure.Provider.Connection' 
     AND msg_t.send_time BETWEEN '2013-06-02' AND '2013-06-03' 
    GROUP BY 
     msg_t.phone, 
     msg_t.sushi_sub_id 

編輯 -

每個編輯試圖澄清電話,sushi_sub_id參考...現在alias.field調整,知道正確的表的字段,我將確保msg_t表上的所有4個部分指標爲查詢。

(狀態,send_time,電話,sushi_sub_id)

至於 「MAX(CASE ...)」。由於這是通過在各列上的重試表的左連接完成的,如果它有任何記錄(1或更多),則「電話」將具有有效值。如果不存在這樣的記錄,則它將是NULL。

2

您錯過了group by子句。我會嘗試與存在更換COUNT(*):

SELECT 
    Sum(CASE WHEN exists(SELECT 1 FROM `retry` AS `rty` 
    WHERE `rty`.`phone` = `msgs`.`phone` 
    AND `rty`.`sushi_subscription_id`=`msgs`.`sushi_sub_id`) 
    THEN 1 ELSE 0 END) AS `In_Retry`, 
    Sum(CASE WHEN exists(SELECT 1 FROM `retry` AS `rty` 
    WHERE `rty`.`phone` = `msgs`.`phone` 
    AND `rty`.`sushi_subscription_id`=`msgs`.`sushi_sub_id`) 
    THEN 0 ELSE 1 END) AS `Not_In_Retry`, 
    phone, sushi_sub_id 
FROM 
    (SELECT phone, sushi_sub_id FROM `yesnotmp`.`msg` 
     LEFT JOIN `yesnotmp`.`msg_t` ON (`msg`.`id`=`msg_t`.`msg_id`) 
     WHERE `msg_t`.`send_time` BETWEEN '2013-06-02' AND '2013-06-03' 
      AND `msg_t`.`status` = 'Failure.Provider.Connection') AS `msgs` 
GROUP BY phone, sushi_sub_id