2014-09-24 33 views
0

此問題是在the back of one I asked earlier today。答案我解決了我的問題,通過限制行返回我可以看到它做我想要的。使用LEFT加入和條件加入更有效的SELECT查詢

但是現在,當我試圖運行整個查詢,沒有限制,出口到Excel分析的目的,我似乎無法得到任何地方。我在那個MySQL工作臺上啓動SQL,再次詢問我的密碼,查詢停止運行。我不確定那條信息是否會發生其他事情,以及我真正的問題是什麼:「如果可以,我怎樣才能使查詢運行得更快?」目前運行至少5分鐘,然後「踢我離開」。

當我在這裏解釋的查詢提供了什麼:

1 SIMPLE co ALL     185610 Using temporary; Using filesort 
1 SIMPLE my ref PRIMARY PRIMARY 4 bm_emails.co.id 23 
1 SIMPLE nvk eq_ref PRIMARY PRIMARY 4 bm_emails.co.id 1 

想必臨時表是造成「使用臨時」是一個問題,但我不能確定如何解決它,同時保持我的查詢。 的實際查詢是在這裏:

SELECT 
    co.email, 
    nvk.nvk_medium, 
    CAST(MIN(co.created) AS DATE) AS first_contact, 
    MIN(CASE WHEN my.my_id = 581 THEN my.data END) AS WA_Created, 
    MIN(CASE WHEN my.my_id = 3347 THEN my.data END) AS WA_Upgraded 
FROM bm_emails.cid208 co 
LEFT JOIN bm_emails.my208 my ON co.id = my.eid AND (my_id = 581 OR my_id = 3347) 
LEFT JOIN bm_emails.nvk208 nvk ON nvk.eid = co.id 
GROUP BY email 
+0

Myworkbench是一個很好的一天......在這裏你的SQL看起來很乾淨,但group by子句(nvk.nvk_medium不是彙總或group by子句中的片狀...任何其他數據庫將返回一個錯誤的它),但我看不到影響性能。桌子有多大? – Twelfth 2014-09-24 18:19:59

回答

0

如果我認爲bm_emails包含每封郵件一行,那麼這可能走得更快:

select co.email, 
     (select nvk.nvk_medium from bm_emails.nvk208 nvk where nvk.eid = co.id limit 1) as nvk_medium, 
     co.created, 
     (select min(my.data) from bm_emails.my208 my where co.id = my.eid and my.mid = 581) as WA_Created, 
     (select min(my.data) from bm_emails.my208 my where co.id = my.eid and my.mid = 3347) as WA_Updated 
from bm_emails.cid208 co; 

這可以採取以下指標的優勢:

bm_emails.nvk208(eid, nvk_medium) 
bm_emails.my208(eid, mid, data) 

當然,這取決於第一個假設,即第一個表每個電子郵件一行。

編輯:

即使有多個電子郵件地址,我仍然會嘗試這個辦法:

select cn.mail, cn.nvk_medium, cn.created, 
     (select min(my.data) from bm_emails.my208 my where co.id = my.eid and my.mid = 581) as WA_Created, 
     (select min(my.data) from bm_emails.my208 my where co.id = my.eid and my.mid = 3347) as WA_Updated 
from (select co.email, nvk.nvk_medium, min(co.created) as created 
     from bm_emails.cid208 co left join 
      bm_emails.nvk208 nvk 
      on nvk.eid = co.id 
     group by co.email, nvk.nvk_medium 
    ) cn; 
+0

通過聲明中的電子郵件來判斷,我不認爲它是每個電子郵件1行。對於一系列子查詢在mysql中運行速度可能會更快,我感到很驚訝,我想這只是更有效地使用索引。 – Twelfth 2014-09-24 18:21:25

+0

@twelfth是正確的,在該表中有多個電子郵件實例 – 2014-09-24 20:29:39

+0

@ Twelfth。 。 。絕對。相關的子查詢可以防止在整個表上進行聚合所需的非常大的外部文件分類。另外,他們可以利用索引。 – 2014-09-24 20:40:41

1

聯盟都往往比在連接條件使用或更快的選擇。檢查數據結果,我認爲使用UNON可能會更有意義,但必須查看數據。我也想知道更多關於whter你想看到bm_emails.cid208記錄,不會加入要麼記錄添加my_id 581或身份識別碼3347.

試試這個:

SELECT email,nvk_medium, CAST(MIN(created) AS DATE) AS first_contact,WA_Created,WA_Upgraded 
FROM 
(
    SELECT 
     co.email, 
     nvk.nvk_medium, 
     co.created AS first_contact, 
     my.data AS WA_Created, 
     NULL AS WA_Upgraded 
    FROM bm_emails.cid208 co 
    LEFT JOIN bm_emails.my208 my ON co.id = my.eid AND my_id = 581 
    LEFT JOIN bm_emails.nvk208 nvk ON nvk.eid = co.id 
    UNION ALL 
    SELECT 
     co.email, 
     nvk.nvk_medium, 
     co.created AS first_contact, 
     NULL AS WA_Created, 
     my.data AS WA_Upgraded 
    FROM bm_emails.cid208 co 
    LEFT JOIN bm_emails.my208 my ON co.id = my.eid AND my_id = 3347 
    LEFT JOIN bm_emails.nvk208 nvk ON nvk.eid = co.id 
) a 
GROUP BY email,nvk_medium,WA_Created,WA_Upgraded 

我也會考慮如果CAST(MIN(created)AS DATE)應該是Min(CAST(創建AS DATE)),取決於創建的字段的數據類型。如果是某種基於字符串的字段,那麼10/20/2014將小於2/24/2013並且將被選中。如果它存儲在日期時間類型的字段中,並且您只是簡單地關閉時間,那麼這樣做可以。

+0

謝謝我嘗試過運行,但同樣的事情發生 - 它跑了一段時間,然後在完成之前踢掉我。有趣的是,@第十二部分關於根據和nvk_medium字段分組的評論。查詢運行時沒有通過(Bad SQL?)將nvk_medium添加到組中。但是,如果我添加它,它不會運行(或在合理的時間範圍內)。這是否暗示瞭解決方案?這是nvk_medium字段 – 2014-09-24 20:31:46

+0

Coudl你發佈你有什麼索引? – HLGEM 2014-09-24 21:01:11