1

我有這兩個查詢的一些性能問題創建軌道指數多列查詢:與日期範圍

any_impression = Impression.exists?(user_id: user_id, created_at: range) 
any_visit  = Visit.exists?(user_id: user_id, created_at: range) 

他們必須爲每個用戶記錄約50萬,並正在採取超過15秒運行。

基於此,我想創建兩個索引,每個搜索一個。

我的問題是,我應該創建索引:

add_index :visits, [:user_id, :created_at] 
add_index :impressions, [:user_id, :created_at] 

還是需要更多的一些具體信息,以上述使用的查詢索引創建的?

非常感謝。

回答

1

這些索引應該沒問題。在Postgres中,索引並不總是知道如何使用給定的運算符---它取決於索引類型。 This page from the manual解釋細節。

您提出的索引應該是btree索引。在我的實驗,告訴ActiveRecord的查詢基於一系列timestamp列產生BETWEEN ... AND ... SQL:

User.where(created_at: (Date.parse('2015-01-01') .. 
         Date.parse('2016-01-01'))).to_sql 

給出:

SELECT "users".* 
FROM "users" 
WHERE ("users"."created_at" BETWEEN '2015-01-01' AND '2016-01-01') 

那是你還看到了什麼?那麼Postgres應該使用你的索引,因爲BETWEEN只是<=>=

您也可以用EXPLAINEXPLAIN ANALYZE手動運行查詢,查看索引是否按照您的預期使用。

+0

感謝您的解釋和鏈接是非常有用的。我創建索引,查詢現在幾毫秒內運行,令人難以置信,非常高效,無論如何,再次感謝= D。 – overallduka