2015-11-06 55 views
1

我在尋找優化這個mysql查詢的幫助。需要超長時間才能運行,因爲main_activity下的兩個表都很龐大(每個超過1000萬行!)。 main_db.members和main_db.customers分別是大約400K和600K行。想優化mysql查詢

編輯:

基礎上建議使用臨時表,只是想補充一點,我正在上一個只讀數據庫查詢,以便臨時表可能是一個問題。不使用臨時表可以做什麼優化?

select distinct 
    a.members_id, 
    a.customer_id, 
    a.subscription, 
    a.buy_date, 
    from_unixtime((max(m2.sales_date)/1000), '%m/%d/%Y') as sales_date, 
    a.return_date, 
    a.signup_date, 
    from_unixtime((max(st.visit_date)/1000), '%m/%d/%Y') as visit_date 
from (select distinct 
      m1.members_id, 
      m1.customer_id, 
      m1.subscription, 
      from_unixtime((m1.buy_date/1000), '%m/%d/%Y') as buy_date, 
      from_unixtime((m1.return_date/1000), '%m/%d/%Y') as return_date, 
      from_unixtime((c.signup_date/1000), '%m/%d/%Y') as signup_date 
     from main_db.members m1 
      join main_db.customer c on c.global_members_id = m1.members_id 
    ) as a 
    left join main_db.members m2 on m2.customer_id = a.customer_id 
    left join main_activity.onlinevisit s on s.customer_id = a.customer_id 
    left join main_activity.storevisit st on st.visit_id = s.visit_id 
+0

我用最大拉最後銷售日期和最後來店更換

max(m2.sales_date) 

來自其他各種表格的日期。我需要提取每種情況下的最後日期。商店訪問和銷售日期分配給每個客戶和會員ID有幾個值。其他字段不需要彙總 – user2022284

+0

@ GordonLinoff歡迎使用MySQL;) – RedFilter

+0

至少包含說明計劃https://dev.mysql.com/doc/refman/5.0/en/using-explain.html –

回答

0

這個想法是創建一個好鑰匙臨時表。我們可以從這開始:

create temporary table a (key(customer_id)) select distinct 
      m1.members_id, 
      m1.customer_id, 
      m1.subscription, 
      from_unixtime((m1.buy_date/1000), '%m/%d/%Y') as buy_date, 
      from_unixtime((m1.return_date/1000), '%m/%d/%Y') as return_date, 
      from_unixtime((c.signup_date/1000), '%m/%d/%Y') as signup_date 
     from main_db.members m1 
      join main_db.customer c on c.global_members_id = m1.members_id; 


select distinct 
    a.members_id, 
    a.customer_id, 
    a.subscription, 
    a.buy_date, 
    from_unixtime((max(m2.sales_date)/1000), '%m/%d/%Y') as sales_date, 
    a.return_date, 
    a.signup_date, 
    from_unixtime((max(st.visit_date)/1000), '%m/%d/%Y') as visit_date 
from a 
    left join main_db.members m2 on m2.customer_id = a.customer_id 
    left join main_activity.onlinevisit s on s.customer_id = a.customer_id 
    left join main_activity.storevisit st on st.visit_id = s.visit_id; 

您需要確保在其他表中也有好的密鑰。

+0

什麼是好鑰匙?你的意思是適當的索引? –

+0

是的,一個可以實際用於查詢的索引。您可能需要s表和m2表中的customer_id以及st表中的visit_id上的密鑰。要找出所有密鑰是否存在,請在最後一個查詢上運行EXPLAIN。 –

+0

再一次,你的意思是'INDEX'就像https://dev.mysql.com/doc/refman/5.7/en/create-index.html當你說主鍵聲音像'主鍵'那些有索引或'外鍵'那些默認情況下沒有索引,其他字段也可以有索引。 –

0

請提供SHOW CREATE TABLE

我希望有指標上

m2.customer_id 
s.customer_id 
st.visit_id 

如果不是,這可能是一個顯著的性能問題。

使用DISTINCT意味着JOINs乘以行數,並且您需要縮小它。沒有DISTINCT,每個查詢都可以正常工作嗎?消除它會節省數據的傳遞。

避免通脹通縮開銷另一種可能性是與

(SELECT max(m2.sales_date) 
     FROM main_db.members m2 
     WHERE m2.customer_id = a.customer_id) 

(ETC)