web-dev-qa-db-ja.com

Postgresqlの主キーと外部キーの自動インデックス作成

PostgreSQL 9.4( http://www.postgresql.org/docs/9.4/static/ddl-constraints.html )の場合、

外部キーは、主キーであるか、一意制約を形成する列を参照する必要があります。つまり、参照される列には常にインデックス(主キーまたは一意制約の基礎となるもの)があります。したがって、参照する行に一致があるかどうかを確認すると効率的です。参照されるテーブルからの行のDELETEまたは参照される列のUPDATEでは、古い値に一致する行を参照するテーブルをスキャンする必要があるため、参照する列にもインデックスを付けることをお勧めします。これは常に必要なわけではなく、インデックスの作成方法には多くの選択肢があるため、外部キー制約を宣言しても、参照する列にインデックスが自動的に作成されるわけではありません。

そして、私はこれらの行の作成者が1つの主要なポイントを見落としているかどうか疑問に思いました:私が親子関係(たとえば、カート位置を持つカート)を持ち、子(カート位置)が親(カート)との関係をマークしている場合特定の親のすべての子を取得するときに、親(カート)の主キーに外部キーを使用する場合は、インデックス付けされていない外部キー列を使用します。

したがって、主キー列とは対照的に、デフォルトで外部キー列のインデックスを生成せず、ユーザーが次善のパフォーマンスを体験できるようにするオーバーヘッドは、インデックスを保守するオーバーヘッドを上回ります。一方、クエリのパフォーマンスのマイナーな改善?

おそらく、誰かがデータベースの実装の詳細とこの決定につながる推論についてより多くの洞察を持っているか、外部ポスト列(Postgresql内)のデフォルトのインデックス生成が気付かれない深刻な問題につながる可能性がある理由を指摘できます。

3
Smutje

外部キー列のデフォルトのインデックス生成が深刻な問題につながるとは思いません。

この選択は各データベース設計者/管理者に任せることは、PostgreSQL開発者からの決断でした。外部キーを作成するときにインデックスを追加するかどうかを選択できます。

もし彼らが反対の決定をしたなら、それから私たちは制限されるでしょう。すべての外部キー制約にはインデックスがあります。誰かがインデックスされていないいくつかの外部キー列を持ちたい場合、それらは制限されるか、強制されます。

これで、外部キー制約に一致させるためにインデックスを追加する必要があるという追加の負担のみが必要になります。

個人的には、ほとんどの場合、外部キー制約にそれぞれのインデックスを追加します。しかし、多くの場合、インデックスは制約と完全には一致しません。たとえば、FkはTABLE c (..., FOREIGN KEY (a_id) REFERENCES a (a_id) )で、_(a_id)_を使用するクエリだけでなく他のクエリにも役立つため、インデックスは単一の_(a_id, b_id)_または複合_a_id_になる場合があります。

または、カバーできる外部キー制約が2つある(よりまれなケース)が、インデックスが1つある場合があります(例:FK (a_id) REFERENCES a (a_id), ... FK (a_id, b_id) REFERENCES b (a_id, b_id))。

インデックスを作成するときは、インデックスのタイプ(btreehash、Gin、Gist、その他のエキゾチックなタイプ)などの多くのオプションもあるので、最適なものを自由に選択できます私たちの状況のた​​めに。

また、Oracle、SQL Server、DB2、Firebirdも_FOREIGN KEY_列のインデックスを自動的に作成しないため、PostgreSQL開発者が単独でいるのとは異なります。そして、私はこの問題について多くの議論があり、彼らは両方の選択肢を検討したと確信しています。私は彼らが決定に至った理由を推測しているだけです。古いPostgresのディスカッションリストを見ると、彼らが検討した実際の理由の詳細がわかる場合があります。

5
ypercubeᵀᴹ