2011-04-27 125 views
1

我有一个表记录CMS的各种事务。它记录用户名,操作和时间。我已经做了以下查询,告诉我每个用户在过去两天中创建了多少事务,但是对于我来说,发送一堆单独的查询在这一点上速度如此之慢。我错过了编写嵌套查询的基本规则吗?Mysql嵌套查询优化

SELECT DISTINCT 
    `username` 
    , (SELECT COUNT(*) 
     FROM `ActivityLog` 
     WHERE `username`=`top`.`username` 
     AND `time` > CURRENT_TIMESTAMP - INTERVAL 2 DAY 
    ) as `count` 
FROM `ActivityLog` as `top` 
WHERE 1; 

回答

2

你可以使用:

SELECT username 
     , COUNT(*) AS count 
    FROM ActivityLog 
    WHERE time > CURRENT_TIMESTAMP - INTERVAL 2 DAY 
    GROUP BY username 

(username, time)的索引将是有益的关于速度。


如果你想与0 transcations(最后2天)的用户,使用此:

SELECT DISTINCT 
    act.username 
    , COALESCE(grp.cnt, 0) AS cnt 
FROM ActivityLog act 
    LEFT JOIN 
    (SELECT username 
      , COUNT(*) AS count 
     FROM ActivityLog 
     WHERE time > CURRENT_TIMESTAMP - INTERVAL 2 DAY 
     GROUP BY username 
    ) AS grp 
    ON grp.username = act.username 

,或者,如果你有一个users表:

SELECT 
    u.username 
    , COALESCE(grp.cnt, 0) AS cnt 
FROM users u 
    LEFT JOIN 
    (SELECT username 
      , COUNT(*) AS count 
     FROM ActivityLog 
     WHERE time > CURRENT_TIMESTAMP - INTERVAL 2 DAY 
     GROUP BY username 
    ) AS grp 
    ON grp.username = u.username 

另一种方法,类似于你的,将是:

SELECT username 
     , SUM(IF(time > CURRENT_TIMESTAMP - INTERVAL 2 DAY, 1, 0)) 
      AS count 
    FROM ActivityLog 
    GROUP BY username 

甚至这个(因为真= 1,假= 0为MySQL):

SELECT username 
     , SUM(time > CURRENT_TIMESTAMP - INTERVAL 2 DAY) 
      AS count 
    FROM ActivityLog 
    GROUP BY username 
+0

哇,非常感谢你ypercube,这工作惊人的更快。你能解释为什么更快吗?我说的是它先前花了34秒,现在花了0.09秒。 但是,它没有返回具有0个事务的用户,其中前一个查询做了。 – mrkmg 2011-04-27 19:47:27

+0

您可以运行'EXPLAIN yourquery'和'EXPLAIN myquery'查看MySQL“计划”如何运行查询。我可以猜测,但它确实取决于你在桌面上的索引,它的大小和数据的分布。 – 2011-04-27 19:52:33

+0

当然更好的是,这是一个查询,然后是一个分组。如果你有一个'时间'的索引,WHERE检查将会很快,在两个查询中。但在你的情况下,MySQL可能必须为表中的每个不同'用户名'运行子查询(并扫描整个表)! – 2011-04-27 19:55:28

0

无需筑巢...

SELECT `username`, COUNT(`username`) as `count` FROM `ActivityLog` WHERE `time` > CURRENT_TIMESTAMP - INTERVAL 2 DAY GROUP BY `username` 

也不要忘记对time如果添加一个索引你想让它变得更快