我使用的是SQLite 3.我有一个表格forums
,有150行,还有一个表posts
,大约有440万。每个帖子都属于一个论坛。
我想从每个论坛中选择最新帖子的时间戳。如果我要求使用SELECT MAX(timestamp) FROM posts WHERE forum_id = 5
的单个最新帖子,则平均需要40毫秒。
我要求列出所有论坛及其最新帖子
SELECT forums.name, max(posts.timestamp)
FROM posts
JOIN forums ON posts.forum_id = forums.id
GROUP BY forums.name
它有效,但需要 500s - 超过12,000x,只能选择150x。如果我只是在我的应用程序中编写一个循环来发出150个单独的选择查询,那么它会更快。
我确实在posts.timestamp
上创建了一个索引,并且组合索引为posts.timestamp, posts.forum_id
。它没有帮助。
我做错了什么?
答案 0 :(得分:2)
我会创建一个索引
create index ix_posts_forumid_timestamp on posts(forum_id, timestamp)
涵盖GROUP BY posts.forum_id
查询,例如以下
select forum_id, max(timestamp)
from posts
group by forum_id
如果在几秒钟内(应该是)处理查询,那么您可以使用forums
测试联接:
select f.name, t.maxTime
from forums f
(
select forum_id, max(timestamp) maxTime
from posts
group by forum_id
) t on t.forum_id = f.forum_id
这样的查询也可以被另一个索引覆盖,但由于你需要所有论坛,我想它并不像第一个索引那么重要。最后,我认为索引下面的查询应该足够快
select f.name, max(p.timestamp) maxTime
from posts p
join forums f on f.forum_id = p.forum_id
group by p.forum_id
答案 1 :(得分:1)
对forums.name
进行分组可能是个问题,因为该列没有索引。尝试对posts.forum_id
进行分组。
如果您尝试使用输出获取论坛名称,可以尝试以下操作:
SELECT forums.name, t.latestTimeStamp
From
(select posts.forum_id, max(posts.timestamp) as latestTimeStamp
FROM posts
GROUP BY forums.forum_id) as t
JOIN forums ON t.forum_id = forums.id