Mysql 每个表处理数百万条记录,查询似乎无法运行和优化,但执行起来需要很长时间

Mysql 每个表处理数百万条记录,查询似乎无法运行和优化,但执行起来需要很长时间,mysql,join,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'

是否有任何方法可以更改或优化此查询以加快执行时间

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

我唯一能建议的是将M表的where条件移动到子查询中,并在那里调用刚才需要的字段:

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
如果需要进行更多优化,您可以尝试不查找最大值,但如果field phone_mobile的索引可能更快,则可以将其限制为1:

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'

查询本身没有明显的异常问题。如果每个表有数百万条记录,那么它的成本可能会很高。对于查询本身,我唯一的建议是更改

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

MySQL应该对date_sub进行一次评估,而不是对date_diff进行数百万次计算


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

您的u.phone\u手机是否已被索引?请将您的db结构与现有索引一起包含在手机上。手机已与ccif、首次\u打开日期和源id一起被索引。现在查询工作正常,返回预期结果感谢回复,我在字段上有索引,但不确定两个表中是否都有ccif的索引,我将进行检查。我已经考虑过改变这个操作来检查打开的DATEI,但是为什么第一个提出的优化将是查询优化器无论如何都不应该考虑的问题。然而,第二个建议是完全错误的。U.phone_mobile既不是分组列,也不是组的聚合函数。MySQL实际上允许这样做,尽管SQL不允许这样做,但每个组只能得到一个值,而且您不一定知道将得到哪个值。然后,您可以通过电话号码订购这些组。这与原始查询完全不同。您的查询将在使用条件联接后检查所有记录,我的第一个查询将在联接前从M表中剪切一些记录,以便可以带来一些speed@JohnBollinger关于组-是的,你是对的,我没有提到,因为我的观点不是关于组,而是关于最大函数。将立即修复:-只有查询优化器可以说明在查询计划的哪个点使用了哪些条件。MySQL可以自由地将WHERE子句中的条件滚动到连接步骤中,并将连接条件拉出以进行后期过滤。没有理由认为您的第一个查询将执行与原始查询不同的操作。
    and U.first_open_date < date_sub(curdate() INTERVAL 120 DAY)