MySQL查询增强性能取决于日期

时间:2013-12-03 11:27:38

标签: php mysql database innodb

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添加索引是什么错误?

1 个答案:

答案 0 :(得分:0)

您的查询中有两个子查询,因此您可以走两次短信列表。试试这个,我认为应该花费一半的时间:

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 shoud的索引可以加速查询使用的过滤器。

如果您还希望在该时间段内看到没有短信的用户,则可以使用LEFT OUTER JOIN代替INNER JOIN ...(确实是所有用户)