慢SQL查询,如何提高此查询速度?

时间:2013-08-22 13:35:14

标签: mysql sql mysqli

我有一个表(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 个答案:

答案 0 :(得分: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;

答案 1 :(得分:2)

你做的很奇怪 - 使用WHEREGROUPORDER条款中的函数。当函数应用于计算条件时,MySQL 永远不会使用索引。因此,您无法对查询执行任何操作,但为了改善您的情况,您应该更改表格结构并将日期存储为DATE列(和单列)。然后按此列创建索引 - 在此之后,您将获得更好的结果。

答案 2 :(得分:0)

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

答案 3 :(得分: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