[pgsql-jp: 28411] Re: updateの性能を向上
Iwao Watanabe
iwao3 @ DSL.gr.jp
2002年 12月 21日 (土) 15:55:50 JST
こんにちは。
----- Original Message -----
From: <fukudami @ ntes.nec.co.jp>
To: <pgsql-jp @ ml.postgresql.jp>
Sent: Friday, December 20, 2002 8:34 PM
Subject: [pgsql-jp: 28403] updateの性能を向上
> 現状、普通にupdateを使用してDBを更新しているのですが、どうも
> 望んだ性能が出ません。現在約40万件レコード登録してあるテーブル
> に対し、下記の様な方式でupdateを実行すると、約15分程度かかって
> しまいます。更新対象のレコード数はそれほど多くは無い(と言っても
> ばらつきはありますが)ので、可能ならば2〜3分程度の性能にしたいです。
> 更新対象のレコード数は、一度に500〜3000程度です。
RDBMSにとって、更新は重たい処理です。
同時利用者がいるかもしれないことが前提なので、
ある人物が更新しているあいだでも、
別の人がその前の状態を見えるようになっているのです。
この約束を守るために更新処理は実質、
SELECT(対象を見つける) +
INSERT(更新後のデータを登録する:
ただしトランザクションが終了するまで他人に見えない) +
DELETE(もとのデータを消す: 本当に消すのはトランザクションの終了時なので
UPDATEの時には 見つけやすいように印をつけているだけかも) をしているのです。
UPDATE の応答速度が妥当かどうか気になるなら、
40万件の実データに対して
SELECTとINSERTとDELETEを個別にかけてみればよいです。
おそらく UPDATEコマンドでかかる時間と、そう差は無いはずです。
同様に遅いのなら、今あるハードウェアで そのDBMSを選ぶ限り
そういうものなのです。
もし差があるなら、クエリの書き方次第で
早くなる余地があるかもしれません。
速度を追求するなら(それが要件として必要なこともあります)
RDBMSで使うテーブルを設計するときに
UPDATE処理が なるべく生じないようにするべきです。
RDBMSはSELECTが一番速く動作します。INDEXはそのための仕掛けですね。
次にINSERTが早く動作します。CONSTRAINTを調べるだけですみますから。
次はDELETEです。消す前に対象を探す必要があるのでSELECTしたあとにDELETEしています。
繰り返しになりますが、UPDATE は大変です。SELECT+INSERT+DELETE していますから。
そして、これを踏まえた対応は… 速度が要求される場面では、
とりあえずDBには更新後の値をINSERTだけしておきます。
人が欲しいデータがあれば、SELECTの条件を工夫して
古いデータを抽出しないようにします。一度に数千件のデータを
見れる人はいませんから 一度に取り出すデータを小出しにしても
オペレータはあまりイライラしません。
あとでゆっくり時間が取れるときに 古いデータ削除するするのです。
こうすると見かけ上 早く動作するシステムができます。
(いえ、オペレータにとっては間違いなく早く動作するシステムです。)
人が見ないようなデータなら少々遅くても、
コンピュータがせっせと動いてくれるので
文句をいう人は、まずいません。
40万件のデータ処理に15分が遅いですか?
充分早いではないですか。
人が同じことを処理して15分で終わるのでしょうか。
(最後はちょっと詭弁)
pgsql-jp メーリングリストの案内