2009-11-18 50 views
0

我有posts,votescomments表。每个帖子可以有N个“是的投票”,N“没有投票”和N个评论。我试图获得按赞成票数排序的一组帖子。SQL加入,计数()和按“是”/“否”投票排序'帖子'

我有一个查询完成此操作,但运行速度太慢。在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 

编辑:

  • VotesComments和既具有post_id FK
  • 在剃光.1sec关闭查询执行的votes表上vote_type_idpost_id和添加一个索引。
+0

你在每个表上定义了哪些键/索引? – Amber 2009-11-18 20:44:38

回答

0

添加一个'yes_count'列并使用触发器更新投票时每个帖子的投票计数。你可以索引这个列,然后它应该非常快。

+0

我喜欢这个想法,虽然有点不成熟的优化?我在这里更清晰地问了我的问题:http://stackoverflow.com/questions/1765040/mysql-fetch-10-posts-each-w-vote-count-sorted-by-vote-count-limited-by - 其中 – nibblebot 2009-11-19 17:24:11

0

使用explain来检查查询执行计划,这样您就可以看到为什么它很慢,通常只需查看计划并稍后创建适当的索引即可。 1.5k和15k表非常小,因此查询速度应该更快。

0

为什么不添加列是和不是?不要在每篇文章中添加新条目,只需增加计数即可。

如果我误解了你的数据库,或者你不能修改它,至少你有votes.post_id的外键post.id?如果您进行任何连接,则外键非常重要。

+0

我需要跟踪每个投票并将其与IP /会话关联以进行速率限制 – nibblebot 2009-11-19 15:02:51

0

首先,当前的查询应该不能编译,因为它使用p为双方的意见和职位表的别名。为是一次没有,一旦:

其次,你要加入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 

第三,您可以验证是否存在帖子,投票和注释之间关系的正确外键。在votes上的(post_id, vote_type_id)索引也可能有所帮助。