美好的一天,我有一个问题,我正在苦苦挣扎,希望有人已经找到了一个聪明的解决方案(我使用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...)
运行是可以接受的。这可以通过一个查询获得吗?
答案 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的索引。
编辑:概括