図4●10万件のバッチ処理を10分から5分に短縮当初はSQL文のチューニングに注力したが効果が薄かった。SQL文の発行回数を抑える方針へ転換し,最終的にはCOBOLロジックに手を入れて5分まで短縮した
図4●10万件のバッチ処理を10分から5分に短縮当初はSQL文のチューニングに注力したが効果が薄かった。SQL文の発行回数を抑える方針へ転換し,最終的にはCOBOLロジックに手を入れて5分まで短縮した
[画像のクリックで拡大表示]

稼働直後から性能不足

 2005年7月からは店舗やコールセンターで受注機能を稼働開始した。だが,運用を担当している飯島勝己氏(プラネット 情報処理本部 情報センター部 環境課 課長)にはまだ解決すべき課題があった。日中,10分ごとに取引先からVAN経由で受注データを収集して,在庫引当・出荷指示を実行するバッチ処理のチューニングである(図4[拡大表示])。新システムでは,取引先が到着日を指定できるようにサービスを向上させたため,場合によっては航空便で届けなければいけない。「出荷指示を出すタイミングはシビアだった」(星光堂 松本氏)。

 しかし,利用店舗の少ない稼働当初でも10分以上かかっていた。10分を超えれば当然次のバッチは起動しない。「バッチ処理の遅れで出荷が遅れたこともある」(星光堂 松本氏)。プラネットの田林氏は,新システムの利用店舗や受注データの増加が見込まれる2005年12月までには性能問題を解消することで,星光堂の了解を得た。目標は,旧システムの3倍のデータ量(10万件)でも5分以内に終了することだ。

 飯島氏はそれまでメインフレームのRDBやネットワーク型DBは熟知していたが,「Oracleは初めての経験。コマンド一つとっても全く勝手が違う」という状況だった。手探りでもチューニングしなければユーザーに迷惑がかかる。しかし,稼働中の業務ロジックは安易に手を入れられない。

SQLチューニングでは限界

 まず飯島氏は処理時間のかかる“重い”SQL文のチューニングに着手した。DBアクセスに300秒以上かかるSQL文を対象に,検索条件の中にテーブル全体を検索してしまう「?пvを使っていたり,数字項目と文字項目を比較していたりする部分を修正。さらにインデックスを追加した上で,それを使うようにSQL文を修正した。だが,10分の壁すら破れなかった。

 思い切ってバッチ処理のすべてのSQL文(約300本)を精査し,ほとんどのSQL文の実行時間を1秒以内に抑えた。それでも10分を切れない。

 そんなとき,飯島氏はバッチ処理におけるOracleの稼働時間が,バッチ処理全体から見て「非常に少ない」ということに気がついた。つまり,性能劣化の主要因がSQL文ではないということだ。飯島氏は別の方法を模索した。

 COBOLプログラム中にSQL文を記述するには「埋め込みSQL」(OracleではPro*COBOL)を利用する。手始めに飯島氏は,埋め込みSQL文に対して2種類の先読み処理を検証した。ロジックへの影響がなく,SQL文の実行時にあらかじめ指定した数の行をOracleから先読みできる「プリフェッチ」と,多少のロジック修正は必要だが,配列単位でまとめてフェッチできる「配列フェッチ」だ。修正期間と影響のリスクを考えて,全プログラムにプリフェッチを利用するように修正。効果があり,バッチ処理時間は7分まで短縮した。

 だがまだ2分短縮する必要がある。飯島氏はここに来て,「COBOLプログラムの業務ロジックそのものに手を入れるしかない」と覚悟を決めた。期限の11月末までは1カ月を切っていたが,無駄なデータを利用していないかという観点でプログラムのロジックに手を入れた。

 対象は,特に多くのテーブルを更新する,処理の重いプログラムだ。慎重な修正の結果,2分間短縮することに成功した。この数カ月を振り返り,「性能を劣化させないためのコーディング規約を,事前に整備しておかなかったのが原因」と田林氏は反省し,今後に生かしていくという。