2013-07-06 99 views
0

這是我面臨的問題。我有一個用戶模型has_one配置文件。我正在運行的查詢是查找屬於current_user異性的所有用戶,然後按照所有用戶的last_logged_in時間對結果進行排序。Rails:索引和優化db查詢

問題是last_logged_in是User模型的一個屬性,而gender則是配置文件模型的一個屬性。有什麼方法可以索引last_logged_in和性別?如果不是,我如何優化查詢以獲得最快的結果?

回答

1

關於性別的指標是不可能有效調用它,除非您要查找表中代表性不足的性別,因此在last_logged_in上指定索引,並在沒有索引的情況下將結果集中的相反性別過濾掉。

如果列與((gender,last_logged_in)上的索引可以用於確切識別哪些行是必需的,那麼這些列可能會在同一張表上,但即使如此,大多數性能改進也會來自能夠通過掃描索引來檢索所需排序順序的行。

堅持索引last_logged_in列,並查找演示用於滿足排序順序的索引的解釋計劃。

+0

索引last_logged_in是一個聰明的想法嗎?因爲last_logged_in列會在用戶登錄和註銷時不斷更新。這會增加維護索引的開銷嗎?它會真的幫助查詢更快嗎? – pratski

+1

是的,我認爲這樣會很好 - 每個用戶的價值只會在他們登錄時更新,這是一個「人類速度」事件,因此不會像每10秒發生一次。如果優化器可以使用它來對結果集進行排序,則索引將是有價值的,因爲替代方法是完全掃描表並對整個集進行排序。 –

1
add_index :users, :last_logged_in 
add_index :profiles, :gender 

這會加快找到所有異性用戶,然後按時間排序。 你不能有交叉表索引。

+0

索引last_logged_in是一個聰明的想法嗎?因爲last_logged_in列會在用戶登錄和註銷時不斷更新。這會增加維護索引的開銷嗎?它會真的幫助查詢更快嗎? – pratski

+1

據我所知,你應該索引你執行搜索或排序的每一列。 –

1

我只是寫了那

查詢您的用戶模型

def self.get_opposite_sex_users(current_user) 
    self.joins([:profile]).where("profiles.gender = ?", (current_user.profile.gender == 'M') ? 'F' : 'M').order('users.last_logged_in DESC') 
end 

在你的行動,你可以通過User.get_opposite_sex_users(current_user)