从表中选择最新的记录并快速制作,如何?

时间:2010-02-09 21:06:56

标签: sql mysql query-optimization grouping groupwise-maximum

美好的一天,我有一个问题,我正在苦苦挣扎,希望有人已经找到了一个聪明的解决方案(我使用MySQL)。

我有这样的表:

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显示DEPENDENT QUERY)。当我将此查询拆分为两个时:

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...)

运行是可以接受的。这可以通过一个查询获得吗?

4 个答案:

答案 0 :(得分:4)

怎么样

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

这将在一个查询中为您提供日志表中每个用户的最大ID!

答案 1 :(得分:1)

如果您一直在寻找特定用户的日志,那么按user_id对日志文件进行分区会加快速度。如果表由用户分区并由id索引,则查询将非常快速地运行。

编辑:请参阅Dominik的查询

答案 2 :(得分: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`)

但即使没有那把钥匙,性能也会下降。

答案 3 :(得分:0)

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

编辑:概括