RDBMSをKey-Value Storageとして使う場合のパフォーマンス計測(H2, MySQL編)

Tokyo Cabinet, QDBM, Lux IOなど、DBM同士のパフォーマンス比較はWebで良く見かけるのですが、MySQLのような普通のRDBMSをKey-Value Storage的に使用した場合、DBMと比べてどれくらい差が付くものなのかイメージが湧かなかったので、実際に計測してみました。

Javaプログラムから、Berkeley DB、H2、MySQLの3種類のストレージを使用しました。条件は以下の通りです。

  • Berkeley DB Java Edition 3.3.75
    • デフォルト設定
  • H2 1.1.106
    • jdbc:h2:file:~/dbmbench
    • Embeddedモードで使用
    • デフォルト設定
    • DDLは以下を使用
create table casket (
  id integer auto_increment primary key,
  key_ varchar(255) binary not null,
  value blob not null
);
create index key_ on casket(key_);
    • insert文は以下を使用
insert into casket (key_, value) values (?, ?)
    • select文は以下を使用
select * from casket where key_ = ?
create table casket (
  id integer auto_increment primary key,
  key_ varchar(255) binary not null,
  value blob not null,
  index (key_)
);
    • insert文、select文はH2と同じ

その他の条件は以下の通りです。

  • Mac OS 10.5.6
  • 2GHz Intel Core 2 Duo, 4GB Memory
  • JVM引数は-Xmx512m
  • keyは8バイト固定。"00000000", "00000001", "00000002", ...
  • random insert, random select
  • 5回ずつ計測し、中央値を採用

レコード数による比較

valueの長さを10バイトに固定して、レコード数を1000から1000000まで変えた計測結果が以下です。時間の単位はmsです。

DBRecord
Count
Value
Length
InsertSelectInsert
/ Record
Select
/ Record
Berkeley1000101390.0130.009
Berkeley1000010120350.0120.0035
Berkeley1000001011705640.01170.0056
Berkeley1000000101334777390.01330.0077
H210001028210.0280.021
H210000103762410.03760.0241
H210000010596054770.05960.0548
H210000001098088834930.09810.0835
MySQL1000102462530.2460.253
MySQL1000010201127570.20110.2757
MySQL1000001020538295110.20540.2951
MySQL1000000102031483040980.20310.3041

上の表をグラフ化したものが以下です。まず合計処理時間です。

1レコード当たりの処理時間です。


レコードサイズによる比較

次は、レコード数を10000に固定して、valueの長さを100バイトから10000バイトまで変えた計測結果です。

DBRecord
Count
Value
Length
InsertSelectInsert
/ Record
Select
/ Record
Berkeley10000100135530.01350.0053
Berkeley10000500134470.01340.0047
Berkeley100001000205480.02050.0048
Berkeley1000050009051330.09050.0133
Berkeley100001000018192670.18190.0267
H2100001003612550.03610.0255
H2100005005994760.05990.0476
H21000010007734290.07730.0429
H21000050001620218731.62020.1873
H210000100001754418561.75440.1856
MySQL10000100255927850.25590.2785
MySQL10000500292928300.29290.283
MySQL100001000380528730.38050.2873
MySQL100005000779930440.77990.3044
MySQL10000100001902032441.9020.3244

上の表の合計処理時間グラフです。

1レコード当たりの処理時間のグラフです。


考察

本エントリーの計測条件において、Berkeley DBは、RDBMSをDBM的に使った場合に比べて、数倍から十数倍程度速いようです。特に、valueのサイズが増加したとき、H2とMySQLではある地点を境に急にパフォーマンスが劣化するので、Berkeley DBの優位性が際立ちます。

Tokyo CabinetやLux IOはBerkeley DBよりもさらに優秀とのことなので、RDBMSの十数倍から100倍くらいは速くなるんじゃないかと思います。