2011-04-27 251 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如果添加一個索引你想讓它變得更快