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  

正しさ:上記のクエリはほとんど機能します。subselect にはその haveが含まvotesれているため、 join を に残しておくと、非表示の投稿が上位 10 位 (投票でランク付け) にある場合、フィールドに NULL を持つレコードが表示される可能性があります。postsis_hidden = 1postsyes_count

パフォーマンス: ~50k の投稿と ~500k の投票があります。私の開発マシンでは、上記のクエリは .4 秒で実行されています。この実行時間以下にとどまりたいです。

インデックス:フィールドをカバーする投票テーブルにインデックスがありますvote_type_id:post_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 に答える