我有posts
,votes
和comments
个表格。每个帖子都可以有N'是投票',N'无投票'和N条评论。我试图获得一组按照投票数排序的帖子。
我有一个查询正是这样做,但运行得太慢了。在1500个帖子和15K票的数据集上,我的开发机器需要0.48秒。我该如何优化呢?
select
p.*,
v.yes,
x.no
from
posts p
left join (select post_id, vote_type_id, count(1) as yes from votes where (vote_type_id = 1) group by post_id) v on v.post_id = p.id
left join (select post_id, vote_type_id, count(1) as no from votes where (vote_type_id = 2) group by post_id) x on x.post_id = p.id
left join (select post_id, count(1) as comment_count from comments group by post_id) p on p.confession_id = p.id
order by
yes desc
limit
0, 10
修改
Votes
和Comments
都有post_id
FK vote_type_id
表中的post_id
和votes
上添加索引,使查询执行中的.1sec无效。答案 0 :(得分:0)
添加'yes_count'列并使用触发器在投票时更新每个帖子的投票计数。您可以索引此列,然后它应该非常快。
答案 1 :(得分:0)
使用explain
检查查询执行计划,以便了解它为什么会变慢,通常只需查看计划并稍后创建适当的索引就足够了。 1.5k和15k表非常小,因此查询速度要快得多。
答案 2 :(得分:0)
为什么不添加列是和否?不是在每个帖子上添加新条目,只需增加计数。
如果我误解了你的数据库或你无法修改它,至少你有一个外键在votes.post_id到post.id?如果你做任何加入,外键是非常重要的。
答案 3 :(得分:0)
首先,您当前的查询不应该编译,因为它使用p
作为注释和posts表的别名。
其次,你加入votes
两次:一次是否,一次是肯定。使用CASE语句,您可以使用单个连接计算两者的总和。这是一个示例查询:
select
p.*,
sum(case when v.vote_type_id = 1 then 1 else 0 end) as yes,
sum(case when v.vote_type_id = 2 then 1 else 0 end) as no,
count(c.id) as comment_count
from posts p
left join votes v on v.post_id = p.id
left join comments c on c.post_id = p.id
order by yes desc
limit 0, 10
第三,您可以验证帖子,投票和评论之间的关系是否存在正确的外键。 (post_id, vote_type_id)
上的votes
索引也可以提供帮助。