2010-02-09 58 views
2

美好的一天,我有一个问题,我正在苦苦挣扎,希望有人已经找到了一个巧妙的解决方案(我使用MySQL)。从表中选择最新的记录并做出这个FAST,怎么样?

我的表是这样的:

Table `log` 
---------- 
id 
inserted 
message 
user_id 

我的目标是选择最后插入记录的用户,使这个快。日志表是巨大的(约900K记录), 所以我的第一种方法是:

SELECT * FROM `log` 
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id` 
WHERE `id` IN 
(
SELECT MAX(`id`) FROM `log` GROUP BY `user_id` 
) 

但似乎它计算子查询的每一行(EXPLAIN显示关联查询)。当我分裂这个查询有两个:

SELECT MAX(`id`) FROM `log` GROUP BY `user_id` 

SELECT * FROM `log` 
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id` 
WHERE `id` IN (....ids from first query...) 

这是可以接受的运行。这可以通过一个查询来实现吗?

回答

1

除了使用GROUP BY来获取组间最大值,你可能要使它成为一个不相关的子查询获取从表中的特定行附加字段。

SELECT 
    la.user_id,la.message 
FROM 
    `log` as la 
INNER JOIN 
    (
    SELECT 
     user_id, MAX(id) AS maxid 
    FROM 
     `log` 
    GROUP BY 
     user_id 
    ) as lb 
ON 
    la.id = lb.maxid 

这个工作最好/最快的,如果你有一个索引

KEY `foo` (`user_id`,`id`) 

但即使没有该键的性能下降。

+0

它的工作原理!万分感谢!这是用SQL方式思考的! – artvolk 2010-02-10 08:58:41

+0

请记住,我不是(我的)SQL专家。其他人可能会提出更好的解决方案(+指出此解决方案的问题)是完全可能的。我冒昧地改变了标签,希望能够“引诱”(甚至)更多的专家来解决这个问题;-) – VolkerK 2010-02-10 09:26:43

4

如何

SELECT user_id, max(id) FROM `log` GROUP BY user_id 

这将使您获得日志表中每个用户的最大ID,全部在一个查询中!

+0

请参阅我的答案以加快速度。 – 2010-02-09 21:17:37

+0

但是,字段“消息”呢?这可能也应该在结果集中。 – VolkerK 2010-02-09 21:40:20

+0

是的,VolkerK是对的,我还需要其他领域(比如'message')。 – artvolk 2010-02-10 08:57:39

1

如果您一直在寻找特定用户的日志,那么通过user_id对日志文件进行分区会加速很多事情。如果该表由用户分区并按id建立索引,则查询将运行得非常快。

编辑:看多米尼克的查询

0

此外,我会确保你有一个user_id索引。

编辑:广义

相关问题