mysql选择时间跨度查询优化

时间:2011-02-01 17:37:38

标签: sql mysql query-optimization

这是正确的,根据我最后一个问题here,我最终提出了这个问题,基本上可以解决任何在任何24小时内下载超过100次的用户。

SELECT *, 
       users.userid AS IP, 
       MAX(ucount)  
  FROM (SELECT t1.user_id, 
               t1.data DE, 
               ADDTIME(t1.data,'24:00:00') A, 
               (SELECT COUNT(1) 
                  FROM downloads t2 
                 WHERE t1.user_id = t2.user_id 
                   AND t1.data <= t2.data 
                   AND ADDTIME(t1.data,'24:00:00') >= t2.data)  ucount 
          FROM downloads t1) t3 
LEFT JOIN users ON users.id = t3.user_id 
    WHERE ucount > 100 
 GROUP BY IP

事情是,拥有〜40k记录的下载表和~9k记录的用户表,这是我明智的表现:

8 rows in set (9.18 sec)

就此而言,EXPLAIN来自这个

+----+--------------------+------------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
| id | select_type        | table      | type   | possible_keys | key     | key_len | ref                   | rows  | Extra                                        |
+----+--------------------+------------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
|  1 | PRIMARY            | <derived2> | ALL    | NULL          | NULL    | NULL    | NULL                  | 38949 | Using where; Using temporary; Using filesort |
|  1 | PRIMARY            | users      | eq_ref | PRIMARY       | PRIMARY | 4       | t3.user_id            |     1 |                                              |
|  2 | DERIVED            | t1         | ALL    | NULL          | NULL    | NULL    | NULL                  | 38949 |                                              |
|  3 | DEPENDENT SUBQUERY | t2         | ref    | users,data    | users   | 4       | admin_beta.t1.user_id |     5 | Using where                                  |
+----+--------------------+------------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
4 rows in set (8.90 sec)

如何改进此类查询?

1 个答案:

答案 0 :(得分:0)

尝试此查询。

SELECT u.*, t4.user_id, t4.data, t4.A, t4.ucount, u.userid AS IP
FROM
(
    select user_id, data, A, ucount,
        @r := case when @g = USER_ID then @r+1 else 1 end rownum,
        @g := user_id
    from
    (select @g:=null) g
    cross join
    (
    select t1.user_id, t1.data, ADDTIME(t1.data,'24:00:00') A, COUNT(*) ucount
    from downloads t1
    inner join downloads t2 on t1.user_id = t2.user_id 
                       AND t1.data <= t2.data 
                       AND ADDTIME(t1.data,'24:00:00') >= t2.data
    GROUP BY t1.user_id, t1.data
    HAVING COUNT(*) > 100
    ORDER BY t1.user_id, ucount desc
    ) t3
) t4
left join users u on u.id = t4.user_id
where t4.rownum = 1