検索処理のパフォーマンスを比較してみた



お詫びとお知らせ:
10/05時点に書いた計測結果に大きな誤りがあったため
表、グラフを訂正しました。
Bhv+CB以外のパターンでEntityへ更新日など「共通カラム」の
設定を行っていない実装で計測してしまっていました。
(実際のMEMBERテーブルの列数の半分ほどしか使っていませんでした)


深くお詫び申し上げます。(記:10/08)

以下、記事本編になります。
(結論に関しては特に変更はありません)


以前に書いた
ついカッとなってS2Dao.NETの機能を使わずに検索処理を書いてみた
の続きになります。
以下の4パターンの実装でパフォーマンスを比較してみました。

  1. DBFlute(Bhv + ConditionBean(以下、CB))
  2. DBFlute(外出しSQL+cursor)
  3. ADO直接使用 + CB
  4. ADO直接使用 + SQLベタ書き



いずれも検索結果はEntity(DBFluteが自動生成したもの)に
詰め込む形で受け取っています。
DBFluteは.NET版の方を使用しています。


同様の比較はHnossさんたちが一年も前に既に行っているらしいのですが、
今(2008年10月時点)のS2Dao+DBFluteの場合だとどうか?
ということで自分なりに計測。


使用した環境は以下の通りです。

  • データベース: MySQL(InnoDB)
  • Seasar.NET/S2Dao.NET 1.3.11
  • DBFlute 0.8.0
  • プロジェクト: DBFluteのExampleプロジェクト(nbasic-example)
  • 対象テーブル: 上記プロジェクトで使われているMEMBERテーブル
    (30000件データ追加)
  • CPU: Core2Duo 2.40GHz
  • メモリ: 2GB
  • HDD: 250GB 7200rpm
  • OS: WindowsXP SP2
  • .NET Framework3.5 SP1
  • 計測方法: 検索処理実行前と実行後でDateTime.Nowを使って差分を出す



結果は以下のようになりました。数値の単位はmsです。
検索件数1件(主キーを条件に1件だけ検索)





実装パターン初回2回目3回目4回目
DBFlute(Bhv+CB)859311515
DBFlute(外出しSQL+cursor)1280626262
ADO + CB45315015
ADO + SQLベタ375000
検索件数20013件(MEMBER_STATUS_CODEを条件に検索)



実装パターン初回2回目3回目4回目
DBFlute(Bhv+CB)4670381038403810
DBFlute(外出しSQL+cursor)2680145014301420
ADO + CB1930151515001500
ADO + SQLベタ1810143014601460
グラフにするとこんな感じ

ちょっと首をかしげたくなる結果が出ている部分もありますが

  • 検索件数:少→初回実行時はADO直接使用が速い、
    2回目以降はほぼ変わらず(人間の感覚では)
  • 検索件数:多→DBFlute(Bhv+CB)だと時間がかかる、
    他はほぼ変わらず(人間の感覚では)

ということが言えるのではないかと思います。

また、処理時間以外の部分で補足すると

上記の4つの実装はメンテナンス性

(DB定義変更時の修正ミスの起こりにくさ、問題発生時の調査しやすさ)の

順に上から並んでいます。




結論としては下記のような形に落ち着くのかなと考えています。

(我ながら無難過ぎて面白くない結論だと思いますが(^^;)

  • 通常の検索: DBFlute(Bhv+CB)
  • バッチなど大量データを扱う場合: DBFlute(外出しSQL,cursor)

そして

  • サーバはあってもDBサーバくらい
  • Webアプリではなくクライアント側でexeを起動

するようなアプリケーション起動時などで

「少しでも速く、より速くっ!!」

という熱血要件が絡んだときは

「ADOを直たたき+

SQLはCB#ToDisplaySqlの戻り値を使う」

というやり方をプッシュしたいと思います。



パフォーマンス比較の続きはこちら