2009-11-18 31 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)索引也可能有所幫助。