先日の Open Source Database Conference で MySQL に洗脳されて帰ってきたので、ちょっくら自宅で検証。
手元の Kondara-2.1 RC1 の MySQL-3.23.44 を起動してみるが、どうも日本語対応してないっぽい。
SPEC を見ても、configure に charset 関係の指定がしてなかったりして。だめじゃんこれ。
MySQL の本家 から 3.23.49 のソースを取ってきて、野良ビルド。
なんだかんだで時間を取られたのでろくに検証できなかった(^^; が、ちょっとだけ。
英辞郎 の、892,200語 のテキストデータ (約45MB) が手元にあったので、これで単純なテーブルを作ってみる。
元データは SJIS で CR+LF なので、EUC + LF (タブ区切り) に変換して、eijiro.txt として保存。
MySQL-3.23.49
> CREATE TABLE eijiro (word text, trans text);
> LOAD DATA INFILE '/***/***/eijiro.txt' INTO TABLE eijiro;
> CREATE INDEX eijiro_idx ON eijiro (word (255));
PostgreSQL-7.1.3
$ CREATE TABLE eijiro (word text, trans text);
$ COPY eijiro FROM '/***/***/eijiro.txt';
$ CREATE INDEX eijiro_idx ON eijiro (word);
$ VACUUM ANALYZE eijiro;
こんな風にデータを投入してインデックス作成。
まず、前方一致でインデックスが使われる検索をしてみる。
MySQL
time echo "select * from eijiro where word like 'happy %';" | mysql -u root test
real 0m0.068s (←数回実行した平均 以下同様)
0.068 - 0.023 = 0.045
PostgreSQL
time echo "select * from eijiro where word like 'happy %';" | psql eijiro
real 0m0.093s
0.093 - 0.038 = 0.055
MySQL
time echo "select * from eijiro where word like 'slash%' order by word;" | mysql -u root test
real 0m0.040s
0.040 - 0.023 = 0.017
PostgreSQL
time echo "select * from eijiro where word like 'slash%' order by word;" | psql eijiro
real 0m0.066s
0.066 - 0.038 = 0.028
MySQL
time echo "select count(*) from eijiro where word like 'admin%';" | mysql -u root test
real 0m0.030s
0.033 - 0.023 = 0.010
PostgreSQL
time echo "select count(*) from eijiro where word like 'admin%';" | psql eijiro
real 0m0.064s
0.064 - 0.038 = 0.026
time で計測してるから、これはクライアントアプリ(mysql, psql) の起動時間も含めて測ってるわけで。
単に (mysql, psql) を起動して終了するまでを time で測ったのが、 mysql = 0.023, psql = 0.038 (これも平均)。
その値を引いた方が、実時間に近いはず。
前評判通り、MySQL のほうが高速。データの fetch を伴う select ではあまり差がないようだが(とはいえ 1.5倍程度はあるから大きいといえば大きい)、
count(*) では差が2倍以上に開く。
次に、インデックスの使われないベタ検索。
MySQL
time echo "select * from eijiro where word like '%computer%';" | mysql -u root test
real 0m3.641s
3.641 - 0.023 = 3.618
PostgreSQL
time echo "select * from eijiro where word like '%computer%';" | psql eijiro
real 0m4.509s
4.509 - 0.038 = 4.471
MySQL
time echo "select count(*) from eijiro where word like '%program%';" | mysql -u root test
real 0m2.722
2.722 - 0.023 = 2.699
PostgreSQL
time echo "select count(*) from eijiro where word like '%program%';" | psql eijiro
real 0m4.026
4.026 - 0.038 = 3.988
MySQL
time echo "select count(*) from eijiro;" | mysql -u root test
real 0m0.025
0.025 - 0.023 = 0.002
PostgreSQL
time echo "select count(*) from eijiro;" | psql eijiro
real 0m2.144
2.144 - 0.038 = 2.106
ベタ検索も同様の結果。count で差が開く傾向。
全件の count で1000倍もの差が出たが、これはおそらく、MySQL は常にテーブルのデータ件数を別テーブルに管理していて、それを返す。
PostgreSQL は毎回全件カウントしなおし、という実装の違いが出ているだけだと思う。
まあこの実験は読み込み only だからデータベースのファイルはおそらく全部キャッシュに乗っているし、クライアントが同時接続して複数の query
を投げることは考慮していないし、本当に参考のとっかかりに過ぎないような実験。
実際の(実務的な)パフォーマンスを測るのだったら、Web アプリを実装して、Apache Bench で同時接続数十の負荷をかけて・・・とかやるべきでしょうな。
思ったよりも PostgreSQL と MySQL の差が開かなくて、ちょっと拍子抜けしてたりもする。
数倍ぐらい軽く違うのかと思ってた(^^;