1

私はこの2つの問合せを持ついくつかのパフォーマンス上の問題を抱えていて、レールに複数列のクエリにインデックスを作成します。日付範囲

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

彼らが、約500K各ユーザのレコードを持っていると15Sが実行するよりも多くを取っています。

これに基づいて、検索ごとに1つずつ、2つのインデックスを作成したいと考えています。

私の質問は、私が作成すべきインデックスがあるさ:

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

または使用上のクエリに多くのいくつかの具体的な情報が必要なインデックスが作成されましたか?

ありがとうございました。

答えて

1

これらのインデックスは正常なはずです。 Postgresでは、インデックスは与えられた演算子の使用方法を常に把握しているわけではありません。インデックスタイプによって異なります。 This page from the manualが詳細を説明しています。

あなたの提案するインデックスはbtreeインデックスです。私の実験では、範囲に基づいてタイムスタンプ列を照会するのActiveRecordを伝えること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') 

あなたも見ているものということですか? BETWEENはちょうど<=>=なので、Postgresはあなたのインデックスを使うべきです。

EXPLAINまたはEXPLAIN ANALYZEというクエリを手動で実行して、インデックスが期待通りに使用されているかどうかを確認することもできます。

+0

説明していただきありがとうございます。リンクは非常に便利です。私はインデックスを作成し、クエリは数ミリ秒で実行されている、信じられないと非常に非常に効率的、とにかく、おかげで再び= D。 – overallduka