外部キーは自動的にインデックスを作成しますか?


389

2つのテーブルを外部キー化すると、そのSQL Serverは子テーブルのインデックスに似たものを作成すると言われています。私はこれが真実であると信じるのに苦労しますが、特にこれに関連することをそこに多く見つけることができません。

これを尋ねる本当の理由は、おそらく15の関連テーブルがあるテーブルに対する削除ステートメントで非常に遅い応答時間が発生しているためです。データベース担当者に聞いたところ、フィールドに外部キーがある場合、インデックスのように機能すると彼は言っています。これであなたの経験は何ですか?すべての外部キーフィールドにインデックスを追加する必要がありますか、それとも単に不要なオーバーヘッドですか?


私はあなたのDB担当者と同じように理解しています-FKは実際にインデックスを作成します。
Vinnie、

9
いいえ-FKは自動的にインデックスを作成しません。作成するのは理にかなっていますが、SQL Serverが自動的に行うわけではありません
marc_s 2009年

47
これをまったく尋ねるのはばかげていません!
marc_s 2009年

5
削除が遅く、削除するテーブルが他のテーブルから参照されている場合、他のテーブルの外部キーにインデックスを付けると、パフォーマンスが向上する可能性があります。これは、SQLが行を削除するときに、行の参照整合性をチェックする必要があるためです。これを行うには、削除する行を参照する他の行が存在しないことを確認する必要があります。
ノエルケネディ

3
これを知らなかったデータベースの人は、トレーニングを真剣に必要としているに違いない。データベースの人々はパフォーマンスに責任があります。この種のことを知ることが彼らの仕事です。これはひどい無能を示唆しています。
HLGEM 2009年

回答:


343

外部キーは制約であり、2つのテーブル間の関係であり、それ自体はインデックスとは関係ありません。

しかし、FK関係を通じて、関連するテーブルを検索して特定の行を単一の値または値の範囲。

したがって、FKに含まれる列にインデックスを付けることは理にかなっていますが、FK自体はインデックスではありません。

Kimberly Trippの優れた記事「SQL Serverが外部キー列へのインデックスの配置を停止したのはいつですか?」


うん。私は、PostgreSQLがインデックスを作成することを確信しています。MySQLがそうだと確信しています。インデックスを作成することには意味がありますが、必須ではありません。結局のところ、DBが検索するたびにテーブルスキャンを実行する必要がある場合、なぜ参照する必要があるのでしょうか。
MBCook 2009年

上記のこの記事は、SQLサーバーやその他のデータベースがFKにインデックスを作成しないため、混乱を招きます。
vsingh

7
@vsingh:それはまさに記事が伝えようとしていることです-FKが自動的にインデックスを作成することはよくある誤解です-それは行いませ
marc_s 2011

5
@MBCookいいえ、PostgreSQLは(少なくとも9.2またはそれ以前のバージョンでは)で定義された外部キー関係の参照側に自動的にインデックスを作成しませREFERENCES。これは、自動的に作成UNIQUEするためのインデックスPRIMARY KEYUNIQUE制約を、とすることを要求するUNIQUEインデックスがために存在して参照する外部キー関係の終わりはなく、自動的に何もしません参照することが1を自分で作るために、多くの場合は良い考えですけれども、終わり。stackoverflow.com/questions/970562/…を
クレイグリンガー

16
- MySQLのInnoDBは両方が必要となり、自動的に外部キーを追加し、インデックス作成されるため、混乱が存在する可能性がありdev.mysql.com/doc/refman/5.5/en/...
humbadsを

42

うわー、答えはマップ全体にあります。だからドキュメントは言う:

FOREIGN KEY制約は、次の理由でインデックスの候補になります。

  • PRIMARY KEY制約への変更は、関連するテーブルのFOREIGN KEY制約でチェックされます。

  • 外部キー列は、1つのテーブルのFOREIGN KEY制約の列を他のテーブルの主キー列または一意のキー列と照合することにより、関連テーブルのデータがクエリで結合されるときに、結合基準でよく使用されます。インデックスにより、Microsoft®SQL Server™2000は、外部キーテーブル内の関連データをすばやく検索できます。ただし、このインデックスを作成する必要はありません。テーブル間にPRIMARY KEYまたはFOREIGN KEY制約が定義されていなくても、2つの関連テーブルのデータを組み合わせることができますが、2つのテーブル間の外部キー関係は、2つのテーブルがキーを使用するクエリで組み合わせるように最適化されていることを示しています。その基準。

したがって、実際にはインデックスが作成されないことは(ドキュメントは少し混乱していますが)かなり明らかなようです。


5
まさに- インデックスの候補です-しかし、自動的に作成されるわけではありません!
IMHO

4
「2つのテーブル間の外部キーの関係は、2つのテーブルがキーを基準として使用するクエリで結合されるように最適化されていることを示しています。」「... 2つのテーブルを最適化する必要があります...」
Yishai

18

いいえ、外部キーフィールドに暗黙のインデックスはありません。それ以外の場合、Microsoftが「外部キーにインデックスを作成する便利な場合が多い」と言うのはなぜですか。同僚が、参照テーブルの外部キーフィールドと参照先テーブルの主キーを混同している可能性があります。主キー暗黙的なインデックスを作成します。


「暗黙のインデックス」とは何ですか?作成せずにab * treeがあることを意味するだけですか?
ステファニーページ

1
@Stephanie Page:私がこの答えのために作成した式で、自動的に作成されるインデックスを意味します。主キーを宣言すると、SQLサーバーはその主キーを自動的に作成してインデックスを作成します。しかし、外部キーを宣言する場合は別です(他の一部のDBシステムはそうします)。
Michael Borgwardt 2012年

7

SQL Serverは、主キーのインデックスを自動作成しますが、外部キーのインデックスは自動作成しません。外部キーのインデックスを作成します。それはおそらくオーバーヘッドの価値があります。


6

たとえば、注文という大きなテーブルと顧客という小さなテーブルがあるとします。注文から顧客への外部キーがあります。これで、顧客を削除する場合、SQL Serverは孤立した注文がないことを確認する必要があります。存在する場合は、エラーが発生します。

注文があるかどうかを確認するには、SQL Serverがビッグ注文テーブルを検索する必要があります。これで、インデックスがある場合、検索は高速になります。ない場合、検索は遅くなります。

したがって、この場合、削除が遅いのは、インデックスがないためと考えられます。特に、SQL Serverがインデックスなしで15の大きなテーブルを検索する必要がある場合。

PS外部キーにON DELETE CASCADEがある場合でも、SQL Serverは注文テーブルを検索する必要がありますが、削除された顧客を参照する注文はすべて削除する必要があります。


まさに-それがFKのインデックスが(ほとんどの場合)意味をなす理由です
marc_s

1
ほとんどの時間?これは、親からの削除に当てはまるようです。ほとんどの場合、あなたが両親から削除した場合、それは本当だと思います。
ステファニーページ

6

外部キーはインデックスを作成しません。代替キー制約(UNIQUE)と主キー制約のみがインデックスを作成します。これは、OracleおよびSQL Serverに当てはまります。


3

私の知る限りではありません。外部キーは、子キーの値も親列のどこかに表されるという制約を追加するだけです。子キーにもインデックスを付ける必要があることをデータベースに伝えるのではなく、制約するだけです。


3

厳密に言えば、外部キーはインデックスとはまったく関係ありません。しかし、私の上のスピーカーが指摘したように、FKルックアップを高速化するためのスピーカーを作成することは理にかなっています。実際、MySQLでは、FK宣言でインデックスを指定しない場合、エンジン(InnoDB)が自動的に作成します。


3

PostgeSqlでは、\ d tablenameを押すとインデックスを自分で確認できます

btreeインデックスは、主キーと一意制約のある列では自動的に作成されていますが、外部キーのある列では作成されていないことがわかります。

私はそれが少なくともpostgresにとってあなたの質問に答えると思います。


申し訳ありませんが、質問がMS SQL Serverに関するものであることに気付きませんでしたが、回答を投稿した後です。それはおそらくまだ誰かを助けることができます...
グレゴール2012

2

MSSQLを指すEntity Framework 6.1が外部キーにインデックスを自動的に追加することに気づきました。


列をインデックスの一部として手動でフラグを付けた場合(たとえば、複数のメンバーに対して複合インデックスを作成している場合)はそうは思いません
Rowland Shaw

0

InnoDB外部キーと参照されたキーのインデックスを必要とするため、外部キーチェックは高速で、テーブルスキャンを必要としません。参照テーブルには、外部キー列が同じ順序で最初の列としてリストされているインデックスが必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.