2016-02-10 21 views
1

假設您爲電視節目創建imdb類型網站。你有許多Show連接episodes和一堆peopleSecond foreign_key加快查詢

現在我鏈接peopleepisodes雖然contribution表 - 但如果我想要的一切節目他們是在一個名單,我必須經歷劇集。

由於此查詢需要很長時間,因此我正在考慮將show_id添加到contributions表。這是常見的做法,以提高業績或有沒有想過的另一種方式?

回答

2

由於此查詢需要較長的時間

你運行一個SQL的解釋計劃表明爲什麼是這樣?什麼是正在運行的實際SQL查詢,並且您是否在執行諸如排序或運行子查詢之類的操作?

如果我理解你的結構是這樣的:

|people| n---1 |contribution| 1---n |episodes| n---1 |shows| 

一個SQL SELECT的排序:

select distinct s.name 
from shows s, 
     episodes e, 
     contribution c 
where c.people_id = <id> 
and c.episode_id = e.id 
and e.show_id = s.id 

真的應該不會有性能問題,除非有在表上沒有索引或者桌子很大。

+0

這是最快的方法我已經能夠來與: s_ids = Episode.joins(:contributions) .where(「contributions.role_name ='guest'」) .where(「contributions.contributable_type ='Episode'」) 。凡( 'contributions.person_id IN()?',self.id) .distinct .pluck( 'episodes.show_id') 所示= Show.where(ID:s_ids) .order('得分DESC NULLS LAST') – Ashbury

+0

您的表格是否已編入索引?如果是這樣,是否索引了正確的列?你是否捕獲了上述AR查詢生成的SQL,並用EXPLAIN實際在MYSQL控制檯中運行它以查看輸出結果? – mcfinnigan

+0

第一個查詢:SELECT DISTINCT episodes.show_id FROM「episodes」INNER JOIN「contributions」ON「contributions」。「contributable_id」=「episodes」。「id」AND「contributions」。「contributable_type」= $ 1 WHERE(contributions.role_name = 'guest')AND(contributions.contributable_type ='Episode')AND(contributions.person_id IN(159))[[「contributing_type」,「Episode」]] – Ashbury

0

下面是使用where id in (...)選擇方式都顯示了一個特定的人出現在

Shows.where(id: Contribution.select("show_id") 
    .join(:episodes) 
    .where(person_id: personId) 
    .group("episodes.show_id")) 

你也可以試試exists

Shows.where("EXISTS(SELECT 1 from contributions c 
    join episodes e on e.id = c.episode_id 
    where c.person_id = ? and e.show_id = shows.id)")