こんにちは村上です。
今日はJavaから離れてDB関連です。
以前はIBMのDB2という製品を使っていましたが、今はPostgreSQLを使うようになっています。
それである案件にて大量のデータを取り込むことがあり、そこでいろいろと大量データ取込のことを調査したのでちょこっと書きたいと思います。
ちなみに案件では数億件のデータを取り込む予定です。
あまり大規模データを扱うことがないので、すごい貴重な案件ですね。
取込調査内容
データを取り込む方法ですが、次の4つでやりました。
- 男気 Insert
- 王道 Copyコマンド
- 邪道 Copyコマンド
- 裏ワザ pg_bulkload
Insertをガチで流して行きます!!
やっぱPostgreSQLの取込の王道はCopyコマンドっしょ!!
Copyコマンドはインデックスがあった時そんなに速くないからインデックスはとりあえずDropしてCopyコマンドっしょ!!インデックス作成は後回し。
お客さんこれ知ってますか?これ速いんでっせ!! ひっひっひっ
です。
検証は100万件のデータを100ファイル取り込みます。生成されるデータは1億件ですね。
以下に結果です。
ちなみにスペックは
メモリ:500M
CPU:1Core
OS:CentOS 6
PostgreSQL:9.2.2
取込データは1行75バイトでファイルは75Mです。
です。
結果
男気 Insert
1分間に15000件ほど取り込みます。
100万件取り込むのに1時間強かかり、1億件の取込は挫折
私に男気がありませんでした。。。
王道 Copyコマンド
最初の100万件は20秒ほどで取込完了でした。
けど、ここからが良くない!!
Insertでインデックスがボトルネックになっているのか
500万件超えたあたりで取込が20分ほどかかるようになってきました。
1億件はあきらめます。。。
邪道 Copyコマンド
最初の100万件は5秒ほどでした。
目を疑いたくなるスピード!!
そして、そのスピードはほとんど衰えること無く遅くても10秒かからないほどです。
1億件の取込が20分弱ぐらいで終了です。爆速。。。
でも、インデックの作成は30分ほどかかりました。
でも合わせて1時間以内というのは魅力的です。
裏ワザ pg_bulkload
pg_bulkloadって何?って人も多いかも知れませんね。
私も知らなかったですけど、ググるといろいろと情報が出てきます。
インストールもそんなに難しくないです。
バージョンはPostgreSQL9.2対応してそうな3.1.2を使いました。
最初の100万件は10秒ほどで、徐々に速度は遅くなり、最後は2分弱ぐらいかかりました。
1億件は2時間半ほどです。
インデックスありでこの速度なんで十分な気がします。
まとめ
速度を気にするのなら、「邪道 Copyコマンド」ですけど、インデックスを削除しないといけないのがネックですね。システムの運用が始まるとサービスは停止せざるを得ないかもしれませんね。
イニシャルデータ作成とかならかなり有効だと思います。
「裏ワザ pg_bulkload」はおそらく現実的に一番良いと思います。
でも速度とトレードオフで犠牲になっていることがあるかもしれません。
まだきちんとは調べられてませんが、トランザクションの制御や取込項目の柔軟な設定とかは難しいと思います。
案件に採用するとなるとそれぞれいろいろと検討して導入してみて下さい。