PostgreSQL Advent Calendar参加作品です。
ネタはいろいろ考えたんだけど、例えばnode.js+plv8jsでjavascriptだけで遊ぶとか、なんかちょっとしたライブラリ書くとか、アイデアはあれど風邪を引いて実行力がないので手抜きにしました。単にpgbench取りました。
ただし手元にあったwubi+ubuntu8.10(新しいバージョンは何故かうちのマシンで動かなかったので何故か古い)でコンパイルできるバージョンを片っ端からインストールするというネタをかましました。本当はWAL導入前の6.5までいきたかったけど、7.2でpg_hba.cがエラーで入らず、直そうかと思ったが手間をかけたくないし断念。
以下のバージョン(全てマイナーバージョンは最終版)を同一マシンにインストールし、挙動を比較する。
取得するデータは以下のとおり。
設定は全部デフォルト(-c 30なのは単に7.4までのmax_connectionのデフォルト値が32のため)
マシンはCore2 Quadに4GBメモリ(ただしOSが32bit)のデスクトップ。ファイルシステムはWubi上のext3, ディストリビューションはUbuntu8.10
ではvacuumなしの劣化に関するベンチをしめす。まずはscale factor=1から。
7.3と7.4がいわゆる「いかにもPostgreSQLらしいベンチ」と昔言われていた右下がりのグラフが第一グループ。それに対してバッファの改善のあった(ちなみにこれは初期のARCではなく後期の2Q、あとたぶんshared_buffersの標準値が増えたのが大きい)8.0が第二グループ。そしてバッファアルゴリズムがCLOCKになって特にマルチプロセッサ性能で劇的に改善を果たした8.1と8.2が第3グループ。
それに比べて8.3移行の先頭は、もはや減ってるようにすら見えないと言う圧巻さで、8.3で導入されたHOT(Heap Only Tuple)の実力を垣間見ることが出来る。最大、最小、平均を取ると以下のとおり。
(マルチプロセッサに弱い)8.0の最大値での落ち込みを除けば順当。それ以外で、上に書いたようなグループ分けが引き続き見て取れる。9.0移行で若干落ち込んで居るように見えるが気にするほどではなく、誤差範囲と考えられる。
同様のデータはsc=10,sc=100でも取ってある。10の時はpgbench標準のbranchesテーブルがボトルネックになる問題がないため、ベンチの数字としてはさらに上がっているが傾向的に似ている。
さらにsc=100について以下に示す。若干分かりづらいが、8.0以上も漸増傾向で、それ以前とは差がある。要因はいろいろ考えられるが、shared_buffersが小さかったからだろうと考えられる。サイズ的にはOSのバッファに乗らなかったことも大きい可能性が高い。
次にselect onlyはバージョン比較のみ示す。sc=1,10では7.3が一番高いという結果になったが、これは「全部OSのバッファに確実に乗るサイズかつ検索のみならshared_buffersが小さいほど良い」というテクニックに沿ったものと考えられる。
一方SC=100ではディスクバッファに収まりきらないせいか、バージョンを経る事に良くなる傾向が得られた。
最後にデータロード時間を示す。グラフの便宜のためにSC=1の場合は実時間の50倍、SC=10は実時間の7倍である。おおむねバージョンアップで改善している感じがあるが、あまり安定していないため「そうらしい」以上の結論を導くのは早計だろう。
意外なことに、7.4の時に「データをロードしてからあとでインデックスをつける」という改良が入っている(ちなみにやったのは筆者だ)が、これの効果をうかがい知ることは出来ない。
多くの項目でPostgreSQLがバージョンを重ねるごとに着実に性能を改善していったのがグラフから散見される。特にその傾向は大容量データで顕著である。もっとも差が付いたケースでは、7.3と9.1では平均値で3倍以上ある。特に7.3リリース時はまだシングルコアが主流であり、現在とはコア数だけでも圧倒的な差がある。ハードまで含めればPostgreSQLデータベースの総合性能は10年間で30-40倍近く向上したと言うと言い過ぎだろうか。
もちろん今回のベンチ自体が場当たりで厳密な結果からはほど遠く、またpgbenchによるOLTP性能だけ、というごく一部の性能要件しか計測していないため、特定バージョンの優劣、例えばvacuumの改善とか、ソートやJOINのアルゴリズムの改善や追加、ログの書き込みを甘くすることによる更新性能の向上や、レプリケーションやホットスタンバイによる複数恒星など他の改善点も多く、をこれで推し量ることは出来ない。
反省点としては、各種パラメーターのチューニングを初期値任せでなおざりにしたことがあげられる。そのために単なる設定デフォルトの変更の効果か内部的な改善かと言うのが非常に分かりづらくなっている。
実際にこのように多数バージョンを比較してみると、歴史的な経緯の考察が非常にわかりやすくできるのではないか、という考えで始めたこの実験だが、取っているデータが平凡であるにもかかわらず、個人的には非常に興味深い結果を出すことが出来たと思う。
追記:使ったベンチマークスクリプト。指定する引数はPostgreSQLのインストールパス
----
明日の担当は@osaponさんです。
ネタはいろいろ考えたんだけど、例えばnode.js+plv8jsでjavascriptだけで遊ぶとか、なんかちょっとしたライブラリ書くとか、アイデアはあれど風邪を引いて実行力がないので手抜きにしました。単にpgbench取りました。
ただし手元にあったwubi+ubuntu8.10(新しいバージョンは何故かうちのマシンで動かなかったので何故か古い)でコンパイルできるバージョンを片っ端からインストールするというネタをかましました。本当はWAL導入前の6.5までいきたかったけど、7.2でpg_hba.cがエラーで入らず、直そうかと思ったが手間をかけたくないし断念。
実験概要
以下のバージョン(全てマイナーバージョンは最終版)を同一マシンにインストールし、挙動を比較する。
- 7.3
- 7.4
- 8.0
- 8.1
- 8.2
- 8.3
- 8.4
- 9.0
- 9.1
取得するデータは以下のとおり。
- pgbench -iのロード速度
- pgbench –c 30 –Sのselectのみクエリ
- pgbench –c 30 -nでvacuumせずクエリ繰り返し劣化を見る
- データベースクラスタ全体のサイズ(初期化直後と、上記vacuum無しベンチの実行後)
設定は全部デフォルト(-c 30なのは単に7.4までのmax_connectionのデフォルト値が32のため)
マシンはCore2 Quadに4GBメモリ(ただしOSが32bit)のデスクトップ。ファイルシステムはWubi上のext3, ディストリビューションはUbuntu8.10
pgbench -nによるtpc-bベンチマークと性能劣化の観測
ではvacuumなしの劣化に関するベンチをしめす。まずはscale factor=1から。
7.3と7.4がいわゆる「いかにもPostgreSQLらしいベンチ」と昔言われていた右下がりのグラフが第一グループ。それに対してバッファの改善のあった(ちなみにこれは初期のARCではなく後期の2Q、あとたぶんshared_buffersの標準値が増えたのが大きい)8.0が第二グループ。そしてバッファアルゴリズムがCLOCKになって特にマルチプロセッサ性能で劇的に改善を果たした8.1と8.2が第3グループ。
それに比べて8.3移行の先頭は、もはや減ってるようにすら見えないと言う圧巻さで、8.3で導入されたHOT(Heap Only Tuple)の実力を垣間見ることが出来る。最大、最小、平均を取ると以下のとおり。
(マルチプロセッサに弱い)8.0の最大値での落ち込みを除けば順当。それ以外で、上に書いたようなグループ分けが引き続き見て取れる。9.0移行で若干落ち込んで居るように見えるが気にするほどではなく、誤差範囲と考えられる。
同様のデータはsc=10,sc=100でも取ってある。10の時はpgbench標準のbranchesテーブルがボトルネックになる問題がないため、ベンチの数字としてはさらに上がっているが傾向的に似ている。
さらにsc=100について以下に示す。若干分かりづらいが、8.0以上も漸増傾向で、それ以前とは差がある。要因はいろいろ考えられるが、shared_buffersが小さかったからだろうと考えられる。サイズ的にはOSのバッファに乗らなかったことも大きい可能性が高い。
単純select文の性能
次にselect onlyはバージョン比較のみ示す。sc=1,10では7.3が一番高いという結果になったが、これは「全部OSのバッファに確実に乗るサイズかつ検索のみならshared_buffersが小さいほど良い」というテクニックに沿ったものと考えられる。
一方SC=100ではディスクバッファに収まりきらないせいか、バージョンを経る事に良くなる傾向が得られた。
バルクデータロード(COPY)
最後にデータロード時間を示す。グラフの便宜のためにSC=1の場合は実時間の50倍、SC=10は実時間の7倍である。おおむねバージョンアップで改善している感じがあるが、あまり安定していないため「そうらしい」以上の結論を導くのは早計だろう。
意外なことに、7.4の時に「データをロードしてからあとでインデックスをつける」という改良が入っている(ちなみにやったのは筆者だ)が、これの効果をうかがい知ることは出来ない。
実験結果の考察
多くの項目でPostgreSQLがバージョンを重ねるごとに着実に性能を改善していったのがグラフから散見される。特にその傾向は大容量データで顕著である。もっとも差が付いたケースでは、7.3と9.1では平均値で3倍以上ある。特に7.3リリース時はまだシングルコアが主流であり、現在とはコア数だけでも圧倒的な差がある。ハードまで含めればPostgreSQLデータベースの総合性能は10年間で30-40倍近く向上したと言うと言い過ぎだろうか。
もちろん今回のベンチ自体が場当たりで厳密な結果からはほど遠く、またpgbenchによるOLTP性能だけ、というごく一部の性能要件しか計測していないため、特定バージョンの優劣、例えばvacuumの改善とか、ソートやJOINのアルゴリズムの改善や追加、ログの書き込みを甘くすることによる更新性能の向上や、レプリケーションやホットスタンバイによる複数恒星など他の改善点も多く、をこれで推し量ることは出来ない。
反省点としては、各種パラメーターのチューニングを初期値任せでなおざりにしたことがあげられる。そのために単なる設定デフォルトの変更の効果か内部的な改善かと言うのが非常に分かりづらくなっている。
実験そのものの考察
実際にこのように多数バージョンを比較してみると、歴史的な経緯の考察が非常にわかりやすくできるのではないか、という考えで始めたこの実験だが、取っているデータが平凡であるにもかかわらず、個人的には非常に興味深い結果を出すことが出来たと思う。
追記:使ったベンチマークスクリプト。指定する引数はPostgreSQLのインストールパス
#!/bin/bash
export PGDATA=/home/yutaka/data
$1/bin/initdb
$1/bin/pg_ctl -w -D /home/yutaka/data start
$1/bin/createdb yutaka
for s in 1 10 100 ;
do
time $1/bin/pgbench -i -s $s
for i in 1 2 3 ; do $1/bin/pgbench -S -c 30 -t 1000 ;done
du -sk $PGDATA
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do $1/bin/pgbench -n -c 30 -t 100 ; done;
du -sk $PGDATA
done
$1/bin/pg_ctl -D /home/yutaka/data stop
rm -fr $PGDATA
----
明日の担当は@osaponさんです。
コメント