1

我有一个包含电话报告列表的表格(call_history),caller_id 是来电者,start_date(DATETIME)是通话日期。我需要制作一份报告,显示每天有多少人第一次打电话。例如:

2013-01-01 - 100
2013-01-02 - 80
2013-01-03 - 90

我有这个查询可以完美地完成它,但它非常慢。start_date 和 caller_id 列都有索引;是否有其他方法可以获取此信息以加快流程?

这是查询:

SELECT SUBSTR(c1.start_date,1,10), COUNT(DISTINCT caller_id)
FROM call_history c1
WHERE NOT EXISTS
 (SELECT id
 FROM call_history c2
 WHERE SUBSTR(c2.start_date,1,10) < SUBSTR(c1.start_date,1,10) 
   AND c2.caller_id=c1.caller_id)
GROUP BY SUBSTR(start_date,1,10)
ORDER BY  SUBSTR(start_date,1,10) desc
4

4 回答 4

5

以下“WHERE SUBSTR(c2.start_date,1,10)”正在破坏您的索引(您不应在 where 子句的左侧执行函数)

请尝试以下操作:

SELECT DATE(c1.start_date), COUNT(caller_id) 
FROM call_history c1 
    LEFT OUTER JOIN call_history c2 on c1.caller_id = c2.caller_id and c2.start_date < c1.start_date 
where c2.id is null 
GROUP BY DATE(start_date) 
ORDER BY start_date desc 

还重新阅读您的问题,我认为这是另一种不使用 NOT EXISTS 的写作方式

SELECT DATE(c1.start_date), COUNT(DISTINCT c1.caller_id) 
FROM call_history c1 
where start_date = 
    (select min(start_date) from call_history c2 where c2.caller_id = c1.caller_id) 
GROUP BY DATE(start_date) 
ORDER BY c1.start_date desc;
于 2013-08-22T13:52:45.300 回答
2

您正在做一件奇怪的事情 - 在WHERE,GROUPORDER子句中使用函数。当函数用于计算条件时,MySQL永远不会使用索引。所以,你不能对这个查询做任何事情,但为了改善你的情况,你应该改变你的表结构并将你的日期存储为DATE列(和单列)。然后按此列创建索引 - 在此之后您将获得更好的结果。

于 2013-08-22T13:41:57.977 回答
0

尝试用左外连接替换 NOT EXISTS。

于 2013-08-22T13:41:15.670 回答
0

好的,这是理想的解决方案,速度现在是 0.01

SELECT first_call_date, COUNT(caller_id) AS caller_count
FROM (
    SELECT caller_id, DATE(MIN(start_date)) AS first_call_date
    FROM call_history 
    GROUP BY caller_id
) AS ch
GROUP BY first_call_date
ORDER BY first_call_date DESC 
于 2013-08-22T16:28:48.703 回答