[pgsql-jp: 33200] Re: insertを早くする方法

Tsunehisa Kazawa kazawa @ ca2.so-net.ne.jp
2004年 6月 11日 (金) 00:42:16 JST


こんばんは。加澤と申します。

custplus wrote:
> 現在、java+JDBCドライバでプログラムを作成しておりますが、
> insertですごく時間が、かかっております。
> 
> 1レコードの長さは、約600バイトで、現在10000件あるテーブルに
> 対して1つのトランザクションで12000件のデータをループで回して
> insertしていますが、大体100件insertするのに、約1分ほどかかっております。
> 
> そのテーブルにはindexも張っていません。制約とかもないです。
> 
> これって遅いですよね、なぜ遅いのか、どうすれば早く処理できるのか?
> 経験上からわかることがあればアドバイスお願いします。
> 
> vacuumdbはしているのですが。。。(fullはしていない)

まずすごく一般的な話になってしまって申し訳ありませんが、何がボトルネック
になっているのかが分からないと正しい対応は出来ないと思います。まずはいろ
いろなところでプロファイリングしてボトルネックを探すところから始めた方が
良いのではないでしょうか。

// もしかしたら PostgreSQL 側ではなく Java 側に原因があるのかもしれ
// ませんし。

> <環境>
>  postgresql 7.4.2
>  java 1.4.2
>  OS redhat(サーバ) メモリ2G

さて、原因が PostgreSQL 側にあることがはっきりしたとして、

「index も張っていない、制約もない」とすると、確かに100レコード/分は遅い
です。こちらの手元では、同じような index、制約のない table にただ insert
するだけのテスト (ruby で書かれたテストコードでした) で、Xeon 3GHz くら
いのマシン (メモリ4Gbytes、SCSI HDD 36Gbytes×2) で 800 レコード/秒くらい
の性能は出せました。

// 1レコードのサイズは 600bytes より小さかったと思います。

以前、単純 insert 性能を上げようと思ってチューニングした時気を付けたことは、

・I/O 競合を避けるために、$PGDATA/pg_xlog ディレクトリと $PGDATA/base
ディレクトリは別ディスク上に置く (シンボリックリンクを使う)。

・wal_sync_method をいろいろ変えてみて、一番性能の良いものを選ぶ。Linux
では fsync or fdatasync が速いようです。

・shared_buffers を大きくしすぎない。PostgreSQL の場合、いくらメモリが
余っていても shared_buffers を大きくしすぎると逆に性能が低下してしまいま
す。下記ページなどを参考に最適な値を見付けてください。
http://www.varlena.com/varlena/GeneralBits/Tidbits/perf.html

・checkpoint_segments を用途に合わせて調整する。単純にスループットを稼ぎ
たい場合はセオリー通り大きめにしますが、pause 時間を短くしたい場合は逆に
小さくする必要があります。checkpoint_segments を最低値の 1 にした場合も
実はそれほどスループットの低下はありません。

などでしょうか。

> 過去ログでいろいと見たのですが。。。。
> copyコマンド使えばいいのでしょうか?
> #copyコマンドってトランザクションできるのでしょうか?

僕は JDBC から COPY は使ったことがないので分かりません。すみません。

それでは、また。

-- 
  ◇   加澤恒央 Tsunehisa KAZAWA
◇  ◇ mailto:kazawa @ ca2.so-net.ne.jphttp://www.digitune.org/




pgsql-jp メーリングリストの案内