0

我想获取一组包含投票数的帖子,按投票数排序(例如)

Post 1 - Post Body blah blah - Votes: 500
Post 2 - Post Body blah blah - Votes: 400
Post 3 - Post Body blah blah - Votes: 300
Post 4 - Post Body blah blah - Votes: 200

我有 2 张桌子:

帖子- 栏 - id, body,is_hidden
投票- 栏 - id, post_id,vote_type_id

这是我尝试过的查询:

SELECT p.*, v.yes_count
FROM posts p
LEFT JOIN
    (SELECT post_id, vote_type_id, COUNT(1) AS yes_count
    FROM votes 
    WHERE (vote_type_id = 1) 
    GROUP BY post_id
    ORDER BY yes_count DESC
    LIMIT 0, 10) v 
ON v.post_id = p.id
WHERE (p.is_hidden = 0)
ORDER BY yes_count DESC
LIMIT 0, 10  

正确性:上面的查询几乎可以工作。子选择包括votesfor poststhat have is_hidden = 1,所以当我离开时 join it to posts,如果隐藏的帖子在前 10 名(按投票排名),我最终会得到yes_count字段上为 NULL 的记录。

表现:我有大约 5 万个帖子和大约 50 万张选票。在我的开发机器上,上述查询在 0.4 秒内运行。我想保持在或低于这个执行时间。

索引:我在 Votes 表上有一个索引,涵盖以下字段:vote_type_idpost_id

解释

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra
1  PRIMARY  p  ALL  NULL  NULL  NULL  NULL  45985  Using where; Using temporary; Using filesort
1  PRIMARY  <derived2>  ALL  NULL  NULL  NULL  NULL  10   
2  DERIVED  votes  ref  VotingPost  VotingPost  4     319881  Using where; Using index; Using temporary; Using filesort
4

1 回答 1

0

尝试

SELECT p.*, count(*) yes_count
FROM posts p
LEFT OUTER JOIN votes v ON (v.post_id = p.id and v.vote_type_id = 1)
WHERE p.is_hidden = 0
GROUP BY p.id
ORDER BY yes_count DESC
LIMIT 0,10

由于这是 mysql,因此仅按 p.id 分组即可(但这不能移植到其他数据库)

于 2009-11-19T18:12:22.123 回答