PostgreSQL MVCCにより、UPDATE
事実上、DELETE
によく似ています プラスINSERT
。トーストされた値の注目すべき例外を除いて-参照:
- Postgresは更新時に行全体を書き換えますか?
(そしてヒープのみのタプルの小さな違い-DELETE
+ INSERT
新しいHOTチェーンを開始しますが、手元のケースとは関係ありません。)
正確には、「削除された」行は、削除がコミットされた後に開始され、後でバキュームされたトランザクションには表示されません。したがって、インデックス操作を含むデータベース側では、事実上違いはありません 2つのステートメントの間。 (例外が適用されますので、読み続けてください。)ネットワークトラフィックが少し増加し(データによって異なります)、少し解析する必要があります。
@araqnidの入力後、HOTの更新をさらに調査し、いくつかのテストを実行しました。 実際には値を変更しない列の更新は違いを生じません HOTアップデートに関する限り。私の答えは成り立ちます。以下の詳細を参照してください。
これはトーストされた属性にも当てはまります。値が実際に変更されない限り、それらにも触れられないためです。 。
ただし 、列ごとのトリガーを使用する場合 (9.0ページで導入)、これには望ましくない副作用がある可能性があります!
トリガーに関するマニュアルを引用します:
...
UPDATE ... SET x = x ...
などのコマンド 列x
でトリガーを起動します 、列の値が変更されていない場合でも 。
大胆な強調鉱山。
抽象化レイヤーは便利です。これらは、SQLに精通していない開発者や、アプリケーションが異なるRDBMS間で移植可能である必要がある場合に役立ちます。欠点としては、パフォーマンスが低下し、追加の障害点が発生する可能性があります。可能な限り避けます。
HOT(ヒープのみのタプル)の更新
ヒープのみのタプルはPostgres8.3で導入され、8.3.4と8.4.9で重要な改善が行われました。
Postgres 8.3のリリースノート:
UPDATE
sおよびDELETE
s失敗したINSERT
と同様に、死んだタプルを残します s。以前はVACUUM
のみ 死んだタプルが取ったスペースを取り戻すことができます。 WithHOTのデッドタプルスペースは、INSERT
時に自動的に再利用できます。 またはUPDATE
インデックス付きの列に変更が加えられていない場合 。これにより、より一貫したパフォーマンスが可能になります。また、HOTは重複するインデックスエントリの追加を回避します。
強調鉱山。また、「変更なし」には、列がすでに保持されているのと同じ値で更新される場合が含まれます。 実際にテストしました 、よくわかりませんでした。
最終的に、ソースコードの広範なREADME.HOTがそれを確認します。
トーストされた列も、HOTの更新の邪魔になりません。 HOTで更新されたタプルは、リレーションのトーストフォーク内の同じ変更されていないタプルにリンクするだけです。 HOT更新は、ターゲットリスト内のトーストされた値(実際に変更されているかどうかに関係なく)でも機能します。トーストされた値が変更された場合、明らかにトースト関係フォークへの書き込みが必要になります。私もそのすべてをテストしました。
私の言葉を信じないで、自分の目で確かめてください。 Postgresは、統計をチェックするためのいくつかの関数を提供します。 UPDATE
を実行します すべての列がある場合とない場合で、違いが生じるかどうかを確認します。
-- Number of rows HOT-updated in table:
SELECT pg_stat_get_tuples_hot_updated('table_name'::regclass::oid)
-- Number of rows HOT-updated in table, in the current transaction:
SELECT pg_stat_get_xact_tuples_hot_updated('table_name'::regclass::oid)
または、pgAdminを使用します。テーブルを選択し、メインウィンドウの[統計]タブを確認します。
HOTの更新は、メインリレーションフォークの同じページに新しいタプルバージョンの余地がある場合にのみ可能であることに注意してください。その条件を強制する簡単な方法の1つは、数行のみを保持する小さなテーブルでテストすることです。ページサイズは通常8kであるため、ページに空きスペースが必要です。