Php MySQL查询增强的性能取决于日期
我有这个表,记录了从我的网站发送的短信 我想为每个用户计算一些数据,例如发送短信的数量和两个日期之间的短信数量之和,但当我执行查询时,需要花费20-30秒的时间才能完成,因为我有数百万条记录 这是我的mysql查询Php MySQL查询增强的性能取决于日期,php,mysql,database,innodb,Php,Mysql,Database,Innodb,我有这个表,记录了从我的网站发送的短信 我想为每个用户计算一些数据,例如发送短信的数量和两个日期之间的短信数量之和,但当我执行查询时,需要花费20-30秒的时间才能完成,因为我有数百万条记录 这是我的mysql查询 Name Type Collation Null Default 1 sms_id int(7) None AUTO_INCREMENT 2 users_id
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
主键:sms_id
外键:用户id、服务器id、专用id
我所有的表都是InnoDB引擎,我已经在它之间建立了关系
我能做些什么来加速这个查询?
将索引添加到sms\u amount和sms\u adddate或其他内容是错误的吗?您的查询中有两个子查询,因此您在sms列表中行走了两倍。试着这样做,我认为应该花一半的时间:
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.sms\u adddate和sms.users\u id应该有它们的索引,以加速查询使用的过滤器
如果您还想看到在此期间没有短信的用户,可以使用左外连接而不是内连接。。。实际上,所有用户的索引都应该位于用于查找记录的列上。。。出现在where部分中的。所以,对于sms_adddate,是的,这是一个很好的想法,什么样的索引可以做。。如果在两列中加一行是好的,我可以单独做还是一起做。。我的意思是,对于每一列,我都会这样做,或者在同一个索引@naveed中一起做-hasan@hazem从这个查询判断,看起来您需要一个跨sms_adddate和user的多列索引_id@colin-莫雷利:添加多列索引还是单列索引正确?@hazem这取决于具体情况。如果您总是同时查询日期和用户,则多列索引可能会产生最佳性能。我复制了您的查询,但比我的查询花费的时间要长得多。您添加了sms_adddate索引吗?这是重要的编辑:另外sms.users\u id应该有一个索引,您可以在这里使用sms\u adddate。我没有这样做,我担心这个过程会花费很长时间,并且会影响到其他用户,因为有数百万条记录,这肯定会花费很长时间,尽管最后它会非常适合这个查询。您可以先在开发环境或类似的环境中使用DB的副本。我已经用索引和过滤器做了很多实验,我可以告诉你这两者之间有很大的区别。
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;