仅从表中选择最新记录并使其快速,如何?
Posted
技术标签:
【中文标题】仅从表中选择最新记录并使其快速,如何?【英文标题】:Select only newest records from table and make this FAST, how? 【发布时间】:2011-01-15 00:11:15 【问题描述】:美好的一天,我有一个一直在苦苦挣扎的问题,希望有人已经找到了一个聪明的解决方案(我使用 mysql)。
我有这样的表:
Table `log`
----------
id
inserted
message
user_id
我的目标是为用户选择最后插入的记录并加快速度。日志表很大(大约 90 万条记录), 所以我的第一个方法是:
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...)
运行是可以接受的。这可以通过一个查询来实现吗?
【问题讨论】:
【参考方案1】:怎么样
SELECT user_id, max(id) FROM `log` GROUP BY user_id
?
这将为您获取日志表中每个用户的最大 ID,一次查询!
【讨论】:
查看我的答案以加快速度。 但是message
这个字段呢?这可能也应该在结果集中。
是的,VolkerK 是对的,我还需要其他字段(如 message
)。【参考方案2】:
除了使用 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`)
但即使没有那个键,性能也会下降。
【讨论】:
有效!万分感谢!这真是用SQL的方式思考! 请记住,我不是(我的)SQL 专家。其他人完全有可能提出更好的解决方案(+指出此解决方案的问题)。我冒昧地更改了标签,希望“引诱”(甚至)更多专家回答这个问题;-)【参考方案3】:如果您一直在寻找特定用户的日志,则按 user_id 对日志文件进行分区会大大加快速度。如果表是按用户分区并按id索引的,查询将运行得非常快。
编辑:查看 Dominik 的查询
【讨论】:
【参考方案4】:此外,我会确保您在 user_id 上有一个索引。
编辑:概括
【讨论】:
以上是关于仅从表中选择最新记录并使其快速,如何?的主要内容,如果未能解决你的问题,请参考以下文章