我的任务是优化以下查询。
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))
这会降低查询速度吗?如何优化?
答案 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
进行比较。