20

UNIQUE列または列のグループに指定された制約は、Postgres DBの書き込みパフォーマンスに何らかの影響を及ぼしますか?内部的にどのように機能しますか?

つまり、新しいレコードの挿入時に一意のチェックを実行しますか?はいの場合、それはどのように行われますか、DBにすでに存在する重複値の線形検索を行いますか?その場合、パフォーマンスに影響を与えると見なされます。つまり、一意の制約の数が多いほど、書き込み/挿入のパフォーマンスが低下しますか?それは本当ですか?

4

1 に答える 1

40

UNIQUE制約またはPRIMARY KEY結果を作成すると、btreeUNIQUEインデックスが作成されます。このインデックスは、インデックス付きの列が変更された場合INSERTに、レコードがed、UPDATEed、またはDELETEdされるたびに更新する必要があります。インデックス付きの列が変更されていない場合、特にページにスペースを作成するデフォルト以外の方法がある場合は、HOT(ヒープのみのタプル最適化)が開始され、インデックスの更新が回避される可能性があります。FILLFACTOR

挿入/更新時のインデックスの更新には時間がかかるため、インデックス付きテーブルへの挿入UNIQUEは、一意のインデックスまたは主キーのないテーブルへの挿入よりも遅くなります。同じことが、にも当てはまりますがUPDATE、更新するタプルを見つけるためにインデックスが使用される場合(およびseqscanを回避する場合)、通常、インデックスがまったくない場合と比較して、正味の勝利になります。タプルを見つけるために別のインデックスが使用されている場合、またはseqscanが高速である場合(小さなテーブルの場合のように)INSERT、インデックスと同じようにメリットはなく、その操作のためにインデックスを更新するための書き込みコストが発生します。これは、インデックスだけでなく、すべてのインデックスに当てはまりUNIQUEます。

INSERTまたはインデックス付きUPDATEの列でUNIQUEは、キーが既存のキーと競合していないことを確認するためにインデックスルックアップが必要です。漠然とした記憶から、これは新しいエントリをインデックスに挿入するプロセスと組み合わされますが、100%確実ではありません。

AFAIKDELETEはインデックスに影響を与えません。xmaxヒープ内のタプルのを設定するだけです。

制約付き列ROLLBACKの挿入または更新が成功した後、トランザクションまたはトランザクションがエラーで中止された場合でも、インデックスは更新されます。autovacuumによる作業は、後でデッドインデックスエントリをクリーンアップします。PostgreSQLマニュアルの同時実行制御を参照してください。UNIQUEVACUUM

これはすべて、インデックスPRIMARY KEYを使用して実装される、にも当てはまります。UNIQUE

PRIMARY KEYによって使用されるインデックスと制約を含むすべてのインデックスは、UNIQUE書き込みパフォーマンスにペナルティを課します。

于 2012-11-02T07:12:54.463 に答える