73

次の SQL ステートメントは、Table1.Table1Column にインデックスを自動的に作成しますか、それとも明示的に作成する必要がありますか?

データベース エンジンは SQL Server 2000 です

       CREATE TABLE [Table1] (
. . .
            CONSTRAINT [FK_Table1_Table2] FOREIGN KEY 
            (
                [Table1Column]
            ) REFERENCES [Table2] (
                [Table2ID]
            )

        )
4

3 に答える 3

65

SQL Server は、外部キーにインデックスを自動的に作成しません。また、MSDNから:

FOREIGN KEY 制約は、別のテーブルの PRIMARY KEY 制約のみにリンクする必要はありません。別のテーブルの UNIQUE 制約の列を参照するように定義することもできます。FOREIGN KEY 制約には null 値を含めることができます。ただし、複合 FOREIGN KEY 制約のいずれかの列に NULL 値が含まれている場合、FOREIGN KEY 制約を構成するすべての値の検証はスキップされます。複合 FOREIGN KEY 制約のすべての値が検証されるようにするには、関係するすべての列で NOT NULL を指定します。

于 2008-11-10T20:05:11.927 に答える
22

Mike の質問を読むと、彼は、FK Constraint が FK があるテーブル (Table1) の FK 列にインデックスを作成するかどうかを尋ねています。答えはノーです。(制約の目的で)これを行う必要はありません一方、制約の「TARGET」として定義された列は、参照されるテーブルの一意のインデックス、または主キーである必要がありますまたは代替キー。(一意のインデックス) または Create Constraint ステートメントは失敗します。

(編集:以下のコメントを明示的に処理するために追加されました-)具体的には、外部キー制約が存在するデータの一貫性を提供する場合。インデックスは、行または FK 側の行の削除についてのみ、DRI 制約のパフォーマンスに影響を与えることができます。制約を使用する場合、挿入または更新中にプロセッサは FK 値を認識し、PK 側の参照テーブルに行が存在するかどうかをチェックする必要があります。そこにはすでにインデックスがあります。PK 側で行を削除する場合、FK 側に行がないことを確認する必要があります。この場合、インデックスはわずかに役立ちます。しかし、これは一般的なシナリオではありません。

ただし、それ以外に、特定のタイプのクエリでは、クエリ プロセッサが、その外部キー列を使用する結合の多側でレコードを検索する必要があります。その外部キーにインデックスが存在すると、結合のパフォーマンスが向上します。ただし、この条件は、外部キー制約の存在ではなく、結合クエリでの FK 列の使用に特有のものです...結合の反対側が PK であるか、他の任意の列であるかは問題ではありません。また、その FK 列に基づいてクエリの結果をフィルター処理または順序付けする必要がある場合は、インデックスが役立ちます... 繰り返しますが、これはその列の外部キー制約とは関係ありません。

于 2008-11-10T20:35:36.547 に答える
8

いいえ、列に外部キーを作成しても、その列にインデックスが自動的に作成されるわけではありません。外部キー列のインデックス作成に失敗すると、次の各状況でテーブル スキャンが発生します。

  • 参照先 (親) テーブルからレコードが削除されるたび。
  • 2 つのテーブルが外部キーで結合されるたびに。
  • FK 列が更新されるたびに。

この例のスキーマでは:

CREATE TABLE MasterOrder (
   MasterOrderID INT PRIMARY KEY)

CREATE TABLE OrderDetail(
   OrderDetailID INT,
   MasterOrderID INT  FOREIGN KEY REFERENCES MasterOrder(MasterOrderID)
)

OrderDetail は、MasterOrder テーブルでレコードが削除されるたびにスキャンされます。OrderMaster と OrderDetail を結合するたびに、OrderDetail テーブル全体もスキャンされます。

   SELECT ..
   FROM 
      MasterOrder ord
      LEFT JOIN OrderDetail det
       ON det.MasterOrderID = ord.MasterOrderID
   WHERE ord.OrderMasterID = @OrderMasterID

一般に、外部キーにインデックスを付けないことは、規則よりもはるかに例外です。

外部キーのインデックスを作成しないケースは、それがまったく利用されない場合です。これにより、サーバーを維持するためのオーバーヘッドが不要になります。型テーブルは、時々このカテゴリに分類されることがあります。例は次のとおりです。

CREATE TABLE CarType (
   CarTypeID INT PRIMARY KEY,
   CarTypeName VARCHAR(25)
)

INSERT CarType .. VALUES(1,'SEDAN')
INSERT CarType .. VALUES(2,'COUP')
INSERT CarType .. VALUES(3,'CONVERTABLE')

CREATE TABLE CarInventory (
   CarInventoryID INT,
   CarTypeID INT  FOREIGN KEY REFERENCES CarType(CarTypeID)
)

CarType.CarTypeID フィールドが更新されることはなく、レコードの削除もほとんど行われないという一般的な仮定を立てると、CarInventory が CarTypeID によって検索されなかった場合、CarInventory.CarTypeID のインデックスを維持するサーバーのオーバーヘッドは不要になります。

于 2015-11-24T23:20:51.947 に答える