【问题标题】:date_format(from_unixtime()) subselect very slowdate_format(from_unixtime()) 子选择非常慢
【发布时间】:2017-11-10 12:25:46
【问题描述】:

我尝试使用以下查询在日期范围内吐出每一天并显示潜在客户、分配和回报的数量:

select 
date_format(from_unixtime(date_created), '%m/%d/%Y') as date_format, 
(select count(distinct(id_lead)) from lead_history where (date_format(from_unixtime(date_created), '%m/%d/%Y') = date_format) and (id_vertical in (2)) and (id_website in (3,8))) as leads,
(select count(id) from assignments where deleted=0 and (date_format(from_unixtime(date_assigned), '%m/%d/%Y') = date_format) and (id_vertical in (2)) and (id_website in (3,8))) as assignments,
(select count(id) from assignments where deleted=1 and (date_format(from_unixtime(date_deleted), '%m/%d/%Y') = date_format) and (id_vertical in (2)) and (id_website in (3,8))) as returns 
from lead_history 
where date_created between 1509494400 and 1512086399 
group by date_format

date_createddate_assigneddate_deleted 字段是表示时间戳的整数。 idid_leadid_verticalid_website 已编入索引。

将索引添加到 date_createddate_assigneddate_deleteddeleted 是否有助于加快速度?我遇到的问题是它非常慢,而且我不确定在使用 date_format(from_unixtime(... 时索引是否会有所帮助

这里是EXPLAIN

【问题讨论】:

  • INDEX(date_created) 需要 WHERE

标签: mysql select indexing count


【解决方案1】:

查看您的代码,您可以将查询重写为 ..

  select 
      date_format(from_unixtime(date_created), '%m/%d/%Y') as date_format
      , count(distinct(h.id_lead) as leads
      , sum(case a.deleted = 1 then 1 else 0 end) assignments
      , sum(case b.deleted = 0 then 1 else 0 end) returns
  from lead_history  h 
  inner join assignments on  a a.date_assigned = h.date_created 
        and a.id_vertical = 2 
        and id_website in (3,8))
  inner join assignments on  b b.deleted = h.date_created 
        and a.id_vertical = 2 
        and id_website in (3,8))
  where date_created between 1509494400 and 1512086399 
  group by date_format

无论如何,你应该避免无用的 () 和嵌套的 (),避免在日期之间进行无用的转换并使用 join 而不是 subselect .. 或至少减少使用 case 的类似 sabuselect

PS 对于什么关注索引,记住对列值使用转换无效,使用相关索引..

【讨论】:

  • 但是我的查询中的计数没有使用 date_created,而是使用 date_assigned 和 date_deleted。
  • 答案已更新..但概念和建议保持不变
  • 这不起作用,因为 date_assigned 是一个 unix 时间戳。因此date_assigned 可能不等于date_created
  • 需要INDEX(id_vertical, date_assigned, id_website)deleted
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 2015-03-18
相关资源
最近更新 更多