オンライン・バッチ処理高速化

オンライン・バッチで高速化が課題になっているプロジェクトがあったので、少しお手伝いが必要になった。
昔いろいろやってきたが、ちょっと忘れ気味なので、整理しておきます。
今回のターゲットは SQL Server

DB設計

・検索インデックスの最適化
アクセスパス分析、PK、FK、データ量から判判断して設定が基本中の基本

・サブタイプの別テーブル化
これは1000万件中の100件などの検索に最適。ビットマップインデックスの代わり。T字だと論理レベルで出てくる。

・カバードインデックス(インデックスオンリー検索)
IO量削減の手法

・RCSI分離レベル
レポート系がある場合はテーブルのロックは影響大なのでこちらを採用。

フレームワーク

・Dapper
パフォーマンス第1なのでナイーブなORMはなし。SQL実行ができるマイクロフレームワークといえば第1候補はDapper。
https://github.com/StackExchange/dapper-dot-net

・BulkCopy
更新系はBulkCopyを使いたい。INSERT文での実行と比較にならないほど高速。50倍ぐらい。
http://dapper-plus.net/ ※さすがDapperこんな拡張もあるんだ

アプリ実装

・ミニバッチ化+並列処理
オンラインバッチの定番。データを分割して並列化。オンライントランザクションの延長線にバッチを考える実装。

・ストリーム処理
CEP(複合イベント処理)をバッチに適用した方式。すべてのデータをシーケンス処理したいような場合に利用。
ある意味昔のファイル転がし処理的な発想で作ることになる。中間ファイルを作る部分がストリーム処理になるだけ。

・NG実装
ストアドプロシージャでのループ処理。レコード処理はNG.すべてセット処理で行う。
大量データのメモリ読み込み。メモリ利用は分割の単位などで調整可能にしておく。

これぐらい考えておけば、それなりにパフォーマンスはでるはず。