Name Type Collation Null Default
1 sms_id int(7) None AUTO_INCREMENT
2 users_id int(5) NULL NULL
3 sms_number varchar(9) No None
4 sms_amount varchar(7) No None
6 server_id tinyint(2) Yes NULL
7 sms_device varchar(1) No None
8 special_id int(6) Yes NULL
9 sms_ip varchar(32) No None
10 sms_adddate timestamp No CURRENT_TIMESTAMP
我有这个表,记录从我的网站发送的短信我想为每个用户计算一些数据,例如发送的短信数量和每个用户两个日期之间的短信数量总和,但是当我执行查询时,需要很长时间才能完成 20-30 秒,因为我有数百万条记录
这是我的 MySQL 查询
select *,
(select count(sms_id) from sms where sms_adddate>11-11-2012 and sms_adddate<11-11-2013 and sms.users_id=users.users_id limit 1 ) as sms_count,
(select sum(sms_amount) from sms where
sms_adddate>11-11-2012 and sms_adddate<11-11-2013 and
sms.users_id=users.users_id limit 1) as sms_amount
from users limit 10
主键:sms_id外键:users_id,server_id,spicial_id
我所有的表都是InnoDB引擎,我已经在它之间建立了关系。
我可以做些什么来加快此查询速度?将索引添加到sms_amount和sms_adddate是错误的还是什么?
您的查询中有两个子查询,因此您遍历短信列表的两倍。试试这个,我认为应该需要一半的时间:
SELECT users.*,
COUNT(DISTINCT sms.sms_id) AS sms_count,
SUM(sms.sms_amount) AS sms_amount
FROM users
INNER JOIN sms
ON users.users_id = sms.users_id
AND sms.sms_adddate>11-11-2012 and sms.sms_adddate<11-11-2013
WHERE 1
GROUP BY users.users_id
# Optionally (extra time consumption): ORDER BY sms_count DESC
LIMIT 10;
此外,字段 sms.sms_adddate 和 sms.users_id 应该有其索引,以加快查询使用的筛选器。
您可以使用LEFT OUTER JOIN
而不是INNER JOIN
如果您还想查看该时间段内没有短信的用户......(确实是所有用户(