0

私は過去数日間、インデックス作成についてかなりの読み物をしてきましたが、多くの制約があるクエリにインデックスを付ける正しい方法を見つけようとしています。配列データ型と GIN および GIST インデックス型をサポートするためにpostgres_ext gemを使用しています。

2つのクエリがあります

.where("a_id IN (?) and b = ? and active = ? and ? != ALL(c) and ? = ANY(d)")
.where("a_id =? and active =? and ? != ALL(c)")

c と d は整数配列です

追加する予定のインデックス:

 add_index :deals, [:a, :b], :where => "active = true"
 add_index :deals [:c, :d], :index_type => :gin, :where => "active = true"

postgres は最初のクエリでこれらの複数列インデックスの両方を使用しますか?

配列データ型は常に "gin" インデックス型にする必要がありますか? または、それらをbツリーインデックスに入れることもできますか?

最後に、両方のクエリで最初のインデックスが「a」に使用されますか?

追加情報:

PostgreSQL 9.1.3 を使用しています

create_table "table", :force => true do |t|
 t.integer  "a_id"    ##foreign key
 t.string   "title"
 t.text     "description",    :default => ""
 t.boolean  "active",           :default => true
 t.datetime "created_at",      :null => false
 t.datetime "updated_at",    :null => false
 t.integer  "b",
 t.integer  "c", :limit => 8,   :array => true
 t.integer  "d",  :array => true
end
4

1 に答える 1

4

配列と GIN に関しては、配列の B ツリー インデックスを使用できますが、「配列に要素が含まれる」などの操作には役立ちません。そのためには GIN または GiST が必要であり、すべての配列タイプの組み込みインデックスとしてサポートされているのは GIN のみです。

intarray拡張機能とその GiST インデックス タイプを整数配列に使用することもできます。これは、書き込み負荷ではパフォーマンスが向上しますが、読み取り負荷ではパフォーマンスが低下します。

Pg が両方のインデックスを使用するかどうかを判断するための最良の方法は、使用EXPLAIN ANALYZEして確認することです。Rails が実行するステートメントを、有効にして PostgreSQL ログから取得するlog_statementか、SQL ログオンをオンにして Rails ログから取得します。次に、で実行psqlexplain analyzeます。auto_explainまたは、拡張機能を使用して、実行中のクエリに関するパフォーマンス レポートをキャプチャします。

Pg は同じフィルター内で GiST または GIN と b-tree インデックスを組み合わせることができないことがわかると思います。インデックスを結合するにはビットマップ インデックス スキャンが必要で、IIRC は 2 つの B ツリー インデックスでのみ使用できます。GiST または GIN インデックスに追加の列を追加する必要があるかもしれませんが、それはインデックスのサイズを劇的に増加させ、その価値がないかもしれません。

explain analyzeサンプルまたは本番データで実際にどのように機能するかを確認するには、実際に使用する必要があります。

複数列のインデックスを操作する場合、少なくとも b ツリー インデックスの場合、Pg はと の両方または両方を(a,b)フィルター処理するクエリにはインデックスを使用できますが、 のみをフィルター処理するクエリには使用できないことに注意してください。インデックスは左から右に使用できます。インデックスの左側にあるすべての値も検索しない限り、インデックスを使用してインデックスの右側の値を検索することはできません。aabb

于 2013-03-09T01:58:04.823 に答える