39

簡単なhas_and_belongs_to_many関連付け:

Person has_and_belongs_to_many :products
Product has_and_belongs_to_many :persons

次のインデックスは両方とも最適なパフォーマンスに役立ちますか?

add_index :person_products, [:person_id, :product_id]
add_index :person_products, [:product_id, :person_id]
4

3 に答える 3

55

閉じる - ほとんどの場合、次のものが必要です。

add_index :person_products, [:person_id, :product_id], :unique => true
add_index :person_products, :product_id

これ:unique => trueは厳密には必須ではなく、人を製品に複数回関連付けることが理にかなっているかどうかによって異なります。よくわからない場合は、おそらく:uniqueフラグが必要です。

インデックス構造の理由は、最新のデータベースはすべて、クエリで指定された順序に関係なく、最初のインデックスを使用して person_id と product_id の両方でクエリを実行できるためです。例えば

SELECT foo FROM bar WHERE person_id = 1 AND product_id = 2
SELECT foo FROM bar WHERE product_id = 2 AND person_id = 1

は同じものとして扱われ、データベースは最初のインデックスを使用するのに十分スマートです。

同様に、only を使用したクエリperson_idは、最初のインデックスを使用して実行することもできます。複数列の B ツリー インデックスは、元の宣言の左側から指定されている場合よりも少ない列を使用できます。

のみを使用するクエリの場合product_id、最初のインデックスに対してこれを実行することはできません (そのインデックスは、一番左の位置に person_id で定義されているため)。したがって、そのフィールドだけでルックアップを有効にするには、別のインデックスが必要です。

複数列の B ツリー インデックス プロパティは、列数の多いインデックスにも適用されます。にインデックスがある場合、順序が定義と一致する限り、そのインデックスを使用して、、などを(person_id, product_id, favorite_color, shirt_size)使用してクエリを実行できます。person_id(person_id, product_id)

于 2013-03-05T01:26:11.697 に答える
4

はい、彼らは役に立ちます。しかし、本当にそれらが必要ですか? それはすべて、あなたがそれをどうするかにかかっています。インデックスをオン(person_id,product_id)にすると、個人に属する製品をすばやく見つけることができますが、特定の製品を所有している個人を見つけるのには役立ちません。また、UNIQUE を強制するので、おそらく使用する必要があります。上の個別のインデックスを使用する(person_id)(product_id)、個人に属する製品と特定の製品を所有する個人の両方を見つけることができます。(person_id,product_id)とのインデックス(product_id,person_id)どちらの場合でも機能し、高速になりますが、より多くのスペースが必要になり、行を挿入/更新するときに少し (ごくわずか) 多くかかります。時間とスペースのオーバーヘッドは、読み取りよりも頻繁に書き込むベースがない限り、ほとんどの場合、それだけの価値があります。個人的には、9.2 のインデックス オンリー スキャンが、両方の列の 2 つのインデックスから大きな恩恵を受けるのを見てきました。したがって、実際の選択は次のいずれかです。

unique index on (col 2, col 1), unique index on (col 1, col 2)

unique Index on (col 1, col 2), index on (col 2)

于 2013-03-04T21:25:55.510 に答える
0

あなたがしていない限り、あなたは1つだけ必要ですunique

add_index :person_products, :person_id
add_index :person_products, :product_id

または両方の列のインデックスの場合

add_index :person_products, [:person_id, :product_id]

これにより、データベース上のこれらの列に対してクエリを実行する際のパフォーマンスが向上します。両方の列が含まれているか、1 つだけが含まれているかは、クエリによって異なります。

http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index

于 2013-03-04T20:38:02.830 に答える