2015-11-06 61 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)