GrowthForecastがMySQL対応したきっかけとしてSQLiteのdead lock問題があったのですが、PRAGMAでチューニングするとパフォーマンスが結構変わることがわかったのでメモ。
やったのは、journal_mode と synchronous の変更。それぞれ
> PRAGMA journal_mode = DELETE | TRUNCATE | PERSIST | MEMORY | WAL | OFF
> PRAGMA synchronous = 0 | OFF | 1 | NORMAL | 2 | FULL
のような感じで変更できる。
それぞれの設定は、
をみるのが良いと思う。journal_mode に指定できるWALについては次のページに書いてある
あと、中途半端感満載だけど以下のページも参考になる
これらの設定を変更しつつベンチマークとってみた結果が以下。ベンチマークはMacbook Air上で取った。
#default
2012-06-08T18:29:58 [INFO] starting benchmark: concurrency: 4, time: 8
2012-06-08T18:30:08 [INFO] done benchmark: score 5560, elapsed 8.082 sec = 687.942 / sec
# journal_mode = WAL
2012-06-08T18:30:08 [INFO] starting benchmark: concurrency: 4, time: 8
2012-06-08T18:30:18 [INFO] done benchmark: score 16624, elapsed 8.032 sec = 2069.632 / sec
# journal_mode = WAL + synchronous = NORMAL
2012-06-08T18:30:18 [INFO] starting benchmark: concurrency: 4, time: 8
2012-06-08T18:30:28 [INFO] done benchmark: score 31283, elapsed 8.000 sec = 3910.348 / sec
# journal_mode = WAL + synchronous = OFF
2012-06-08T18:30:28 [INFO] starting benchmark: concurrency: 4, time: 8
2012-06-08T18:30:38 [INFO] done benchmark: score 33307, elapsed 8.003 sec = 4161.728 / sec
default から「journal_mode = WAL + synchronous = NORMAL」に変更すると、約5.6倍も高速化される。synchronous = NORMAL と OFF の差が少ないのはデータ量の影響でしょうか。データの安全性とのバランスを取ってもsynchronous = NORMALが良さそうです。
ベンチマークスクリプトはgistに張った。
ベンチマークでは fujiwaraさんの Parallel::Benchmark
を使った。便利!
この結果を踏まえ、DBIx::Sunny では接続した際にデフォルトで
$dbh->do("PRAGMA journal_mode = WAL");
$dbh->do("PRAGMA synchronous = NORMAL");
が実行されるようにして、バージョン 0.16 にアップデートしました。CloudForecastやGrowthForecastは個別に対応を入れてます。