次のような構造のテーブルがあります。次に、データ整合性の観点から、product_id
とitem_id
に結合一意性インデックスを追加します。現在、約100K product_id
と50k item_id
が存在する可能性があります。通常、私のクエリはSelect item_id from product_items where product_id = 'some-id' and item_type=2
を使用します。この場合、一意性インデックスで十分ですか、またはproduct_id
にも個別のインデックスを追加する必要がありますか?一意のインデックスを作成するときに一意性の順序も重要です
product_items
:id,
:product_id
:item_id
:item_type (int)
:created_at
:updated_at
あなたのDBMSが指定されていないので、私は一般的な言葉で応答します。
一意性インデックスが最初の列としてproduct_id
を指定し、2番目の列としてitem_id
を指定すると、インデックスを使用してproduct_id
およびitem_id
に基づいて特定の行を見つけることができます。特定のproduct_id
のすべての行。
クエリは、インデックスの一部として定義された最初の列を使用するときに検索を高速化するためにインデックスを使用でき、WHERE
の場合、インデックスの最初のn列に基づいて行を見つけます節(またはJOIN
条件)は、最初のn行をすべて使用します。
したがって、product_id
がインデックスの作成でリストされた最初の列である場合、product_id
に基づいてレコードを検索するときにいつでも使用できます。 SELECT product_id FROM product_items where item_id = 'some-id' and created_at > '2018-01-01'
は一意のインデックスの最初の列ではないため、インデックスはnotがitem_id
に使用されます。
注:クエリがSELECT product_id FROM product_items WHERE item_id = 'some-id'
の場合、一意の(非クラスター化)インデックスがスキャンされる可能性があります。これはカバーするインデックスになるためです。クエリに必要なすべての列がインデックスに存在するため、DBエンジンはインデックスをproduct_items
テーブル自体のように扱うことができ、テーブル全体ではなくインデックスを読み取るだけで、完全なデータ行。 (一意のインデックスもproduct_items
のクラスター化インデックスである場合、インデックスisテーブル)。