オンライン・バッチ処理高速化
オンライン・バッチで高速化が課題になっているプロジェクトがあったので、少しお手伝いが必要になった。
昔いろいろやってきたが、ちょっと忘れ気味なので、整理しておきます。
今回のターゲットは 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.すべてセット処理で行う。
大量データのメモリ読み込み。メモリ利用は分割の単位などで調整可能にしておく。
これぐらい考えておけば、それなりにパフォーマンスはでるはず。