每个表处理几百万条记录,查询似乎正在工作和优化,但需要很长时间才能执行

时间:2015-04-14 16:38:36

标签: mysql join

有没有办法更改或优化此查询以加快执行时间?

select 
    max(U.phone_mobile) as mobile_number
from 
    ccr_prod.ccr_unique_member as U 
inner join ccr_prod.ccr_member as M 
    on U.ccif = M.ccif and U.first_open_date = M.first_open_date
where M.source_id not in ('FPT', 'VLINK') 
    and U.phone_mobile not in ('', '0')
    and datediff(curdate(), U.first_open_date) > 120
group by 
    U.ccif

2 个答案:

答案 0 :(得分:0)

查询本身没有明显的严重问题。如果每个表有数百万条记录,则可能成本很高。我建议查询本身唯一的就是改变

    and datediff(curdate(), U.first_open_date) > 120

    and U.first_open_date < date_sub(curdate() INTERVAL 120 DAY)

MySQL可以(应该)一次性评估date_sub(),而不是计算date_diff()数百万次。

除此之外,请确保您在ccr_prod.ccr_unique_member.ccifccr_prod.ccr_member.ccif上有索引。

答案 1 :(得分:-1)

我唯一可以建议的东西(移动到M表进入子查询的条件并在那里调用只需要的字段):

select 
    max(U.phone_mobile) as mobile_number
from 
    ccr_prod.ccr_unique_member as U 
inner join ( 
    select 
      ccif, first_open_date
    FROM 
      ccr_prod.ccr_member 
    where 
      source_id not in ('FPT', 'VLINK')
) as M 
  on U.ccif = M.ccif and U.first_open_date = M.first_open_date
where  U.phone_mobile not in ('', '0')
    and datediff(curdate(), U.first_open_date) > 120
group by 
    U.ccif

如果有必要优化更多,如果字段LIMIT 1是可能更快的索引,则可以尝试不查找max phone_mobile

select 
    U.phone_mobile as mobile_number
from 
    ccr_prod.ccr_unique_member as U 
inner join ( 
    select 
      ccif, first_open_date
    FROM 
      ccr_prod.ccr_member 
    where 
      source_id not in ('FPT', 'VLINK')
) as M 
  on U.ccif = M.ccif and U.first_open_date = M.first_open_date
where  U.phone_mobile not in ('', '0')
    and datediff(curdate(), U.first_open_date) > 120
OREDR BY
    U.phone_mobile DESC 
LIMIT 1

如果替换此条件,您可以提高性能:

datediff(curdate(), U.first_open_date) > 120

有一些常数准备如:

U.first_open_date < '2014-12-20 00:00:00'