`from_unixtime`可以减慢这个查询吗?

时间:2017-12-28 19:20:17

标签: mysql

我的任务是优化以下查询。

select
c.account_key,
c.cohort,
date(concat(year(from_unixtime(min(f.processdate_est_key))), '-', 
month(from_unixtime(min(f.processdate_est_key))), '-1')) as 
customer_conversion_month
from
bidw_stage.cohort c left join
bidw.fact f
on
c.account_key = f.account_key and
f.usage_dollars != 0 and
12 * (year(from_unixtime(f.processdate_est_key)) - year(c.cohort)) + 
 (month(from_unixtime(f.processdate_est_key)) - month(c.cohort)) >= 2
group by c.account_key, c.cohort;

去年1月完成了30秒。现在需要将近3分钟。事实表包含大约3000万条记录,队列表大约为20k。事实表属性' account_key'已被编入索引,但并未列入'队列'表。

我没有写这个查询,原始编码器没有留下关于这个原因的文件

12 * (year(from_unixtime(f.processdate_est_key)) - year(c.cohort)) + 
   (month(from_unixtime(f.processdate_est_key)) - month(c.cohort))

这会降低查询速度吗?如何优化?

1 个答案:

答案 0 :(得分:0)

如果在索引的列上调用函数,则索引无效。您需要编写一个条件,将索引列的未修改值与某些内容进行比较。

您的查询测试的条件是processdate_est_key至少在cohort后的第二个月。我们需要在该月初生成一个unix timstamp并与之进行比较,而不是将此列转换为日期并从中提取年份和月份。

AND f.processdate_est_key >= 
        UNIX_TIMESTAMP(CONCAT(YEAR(c.cohort + INTERVAL 2 MONTH),
                              MONTH(c.cohort + INTERVAL 2 MONTH), '01'))

连接获取c.cohort后2个月的日期,提取该年份和月份,追加01以引用该月的第一天。然后,它会调用UNIX_TIMESTAMP将其转换为数字形式,以便与f.processdate_est_key进行比较。