導入
COBOLのテーブル操作において、データ量が増大した際の検索処理はパフォーマンス上のボトルネックになりがちです。特に「支店コード」と「担当者ID」のような複数の項目を組み合わせて一意に特定するケースでは、単純なSEARCH文(逐次検索)では計算量が膨大になります。本稿では、SEARCH ALL文を用いて複合キーで二分探索(バイナリサーチ)を行う手法を解説します。この手法を習得することで、DBのインデックス検索に近い高速なメモリ内処理が可能になります。
基礎知識
SEARCH ALL文は、テーブルがASCENDING(昇順)またはDESCENDING(降順)で定義されている場合にのみ使用可能な「二分探索命令」です。通常のSEARCH文が先頭から順に全件走査するのに対し、SEARCH ALLはデータを半分ずつ絞り込んでいくため、処理速度が劇的に向上します。複合キーを用いる場合は、キーの優先順位(主キー・副キー)に合わせて、定義順序と検索条件の論理積(AND)を正確に記述する必要があります。
実装/解決策
複合キーによる検索を成功させるための必須条件は「テーブルの定義順」と「WHEN句の順序」を一致させることです。まず、OCCURS句のASCENDING KEYに、複合キーを構成する項目を主・副の順で並べます。検索時には、WHEN句でそれらの項目をANDでつなぐことで、コンパイラは複合キーとして認識し、最適化された二分探索ロジックを生成します。
サンプルプログラム
以下のコードは、支店コードと担当者IDを複合キーとして検索する実用例です。
IDENTIFICATION DIVISION.
PROGRAM-ID. SEARCH-COMPLEX-KEY.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TABLE-DATA.
05 BRANCH-TABLE OCCURS 100 TIMES
ASCENDING KEY IS BT-BRANCH-CODE BT-STAFF-ID
INDEXED BY IDX.
10 BT-BRANCH-CODE PIC X(03).
10 BT-STAFF-ID PIC X(05).
10 BT-DATA PIC X(20).
01 SEARCH-VAL.
05 TARGET-BRANCH PIC X(03) VALUE ‘001’.
05 TARGET-STAFF PIC X(05) VALUE ‘A1234’.
PROCEDURE DIVISION.
> SEARCH ALLを実行する前に、テーブルがキー順にソートされていることが前提
SEARCH ALL BRANCH-TABLE
WHEN BT-BRANCH-CODE(IDX) = TARGET-BRANCH
AND BT-STAFF-ID(IDX) = TARGET-STAFF
DISPLAY “見つかりました: ” BT-DATA(IDX)
WHEN AT END
DISPLAY “該当データなし”
END-SEARCH.
STOP RUN.
応用・注意点
現場でよくある失敗は、「ソート順序の不一致」です。ASCENDING KEYに指定した順番と、実際のデータが入っている順番が異なると、SEARCH ALLは誤った結果を返したり、データが見つからない現象を引き起こします。
また、キー項目には必ず値をセットしてからSEARCH ALLを実行してください。一部の古いコンパイラでは、キー項目が初期化されていない場合に予期せぬ動作をすることがあります。大規模テーブルであればあるほど、SEARCH ALLの恩恵は絶大ですが、ソートメンテナンスのコストとのトレードオフになる点も念頭に置いておきましょう。

コメント