Pega 公開列とインデックス設計|BLOB格納とレポート性能の最適化
レポートが遅い、フィルタが効かない——原因の多くは非公開プロパティへのアクセスで BLOB 展開が発生していることにある。公開列とインデックスは万能ではなく、増やすほど書き込みは重くなる。本記事は何を公開し何を BLOB に残すかの判断基準を扱う。
結論から:SQL で絞り込む列だけを公開し、残りは BLOB に置く
Pega の「レポートが遅い」「一覧のフィルタが効かない/異様に重い」という相談の多くは、データの持ち方ではなく 格納の仕組みに対する誤解から来ています。Pega はケースのクリップボードデータ全体を圧縮・シリアライズして、テーブルの Storage Stream 列(pzPVStream)という 1 つの BLOB にまとめて格納します。つまり、あなたが定義した数十・数百のプロパティは、既定では個別の物理列としては存在せず、BLOB の中に畳み込まれています。
物理的な列(データベースのカラム)として姿を現すのは、「公開(最適化)」したプロパティだけです。結論を先に言えば、判断はこうなります。
レポート/検索/SQL でフィルタ・ソート・結合に使うプロパティだけを公開列にする。使わないものは BLOB のまま残す。スカラー(単一値)でない埋め込みページや Page List 内の値は、Declare Index で別のインデックステーブルにする。
公開列とインデックスは読み取りを速くしますが、そのぶん書き込みとテーブル幅のコストを増やします。「とりあえず全部公開」も「必要な列を公開し忘れ」も、どちらも性能問題になります。本記事は、この線引きを設計の型として整理します。
Pega はケースデータをどう格納しているか
Pega のケース(ワークオブジェクト)は、クリップボード上に階層的なページ構造として展開されます。保存時、Pega はこのクリップボードのデータ全体を圧縮・シリアライズし、テーブルの pzPVStream 列に BLOB として書き込みます。BLOB は「ケースの状態をまるごと復元できる完全なスナップショット」であり、ケースを開くたびにここから展開されてクリップボードが再構築されます。公式ドキュメントでも、Single Value 以外のモード(Page や Page List など)のプロパティ値は、この Storage Stream(pzPVStream)に格納されると明記されています。
この設計には大きな利点があります。プロパティを追加してもスキーマ変更(ALTER TABLE)が不要で、柔軟にデータモデルを進化させられる。半面、代償もあります。BLOB の中身は、データベースから見れば不透明なバイト列です。SQL は BLOB の内部を条件に使えません。「金額が 100 万円以上のケース」を BLOB の中の値で絞り込もうとすると、行を読み出して BLOB を展開し、中を見て初めて判定できる——つまり実質的にフルスキャンになります。
そこで登場するのが「公開(最適化)」です。あるプロパティを公開すると、Pega はそのプロパティ用の物理列をテーブルに用意し、保存のたびに BLOB とは別にその列へ値を書き込みます。公式ドキュメントは、スキーマ上の多くの列は Single Value モードのスカラープロパティに対応する「公開列(exposed columns)」であると説明しています。公開された列は普通のカラムなので、SQL で WHERE や ORDER BY に使え、インデックスも張れます。
公開列が必要になる場面
公開列(最適化プロパティ)は、次のように「データベースがそのプロパティを直接見る」必要がある場面で不可欠です。
- Report Definition のフィルタ列・ソート列 — 一覧の絞り込みや並べ替えに使う値
- Obj-Browse の
where条件 — リストを取得する処理での条件指定 - SQL 直接アクセス — 外部 BI ツールや連携でテーブルを直接参照するケース
- テーブル結合(join) — 他クラス/他テーブルと結合するためのキー
逆に言えば、これらに使わないプロパティを公開する理由はありません。詳細メモ、計算の中間値、画面表示専用の付随情報などは、BLOB に残しておけば十分です。ケースを開けばクリップボードに展開されて普通に読めるので、「SQL から絞り込む必要がない」限り公開は不要です。
埋め込みページ・Page List は Declare Index で
公開できるのは**トップレベルのスカラー(単一値)**のプロパティです。ケース直下の「ステータス」「金額」のような単一値は、そのまま物理列にできます。
ところが、埋め込みページの中のプロパティや、**Page List(明細行のような繰り返し構造)**の中の値は、1 対 1 の単純なスカラー列に落とせません。1 件のケースに明細が何行もあるとき、「明細の商品コードで検索したい」と思っても、行ごとに値が異なるため親テーブルの 1 カラムでは表現できないのです。公式ドキュメントも、集約(aggregate)プロパティに埋め込まれているために公開列にできないプロパティは、インデックスで検索・レポート性能を改善できると説明しています。
このために使うのが Declare Index です。Declare Index を定義すると、Pega は埋め込み/Page List の各要素を別のインデックステーブル(Index- クラス)の行として展開し、そこに必要なキー項目を物理列として持たせます。これにより、明細レベルの値でもレポートや検索で効率的に絞り込めるようになります。「親ケースは 1 件だが、その中の繰り返し要素を検索対象にしたい」ときの標準的な解が Declare Index だと覚えておくとよいでしょう。なお、Property Optimization(Optimize for reporting)ツールで埋め込みプロパティを最適化すると、対応する Index- クラスと Declare Index ルールを自動生成してくれます。
トレードオフ:読みは速く、書きは重く
ここが設計判断の核心です。公開列も DB インデックスも、読み取りを速くする代わりに書き込みを重くします。公式ドキュメントも「Single Value プロパティを列として公開すればレポートと検索の性能を大きく改善できるが、挿入と更新の操作を遅くしうる」と明言しています。
| 観点 | 公開列にする | BLOB のまま(非公開) |
|---|---|---|
| レポート/SQL での絞り込み | 物理列として高速(インデックス可) | BLOB 展開が必要で実質フルスキャン |
| ソート・結合(join) | 可能 | 効率的には不可 |
| 書き込みコスト | 列更新(+インデックス更新)の分だけ重い | 軽い(BLOB 書き込みのみ) |
| テーブル幅 | 公開列を増やすほど拡大 | 影響しない |
| 向いているプロパティ | 検索キー・フィルタ列・ソート列 | 明細・中間値・表示専用の付随情報 |
保存のたびに、公開列にはすべて値が書き込まれ、その列にインデックスがあればインデックスも更新されます。公開列が 5 個なら小さなコストですが、100 個公開すればテーブルは横に広がり、1 回の更新で 100 列+関連インデックスを触ることになります。過剰な公開・過剰なインデックスは、更新の多い業務ほど性能を削ります。「読みたい列」ではなく「SQL で絞り込む・並べ替える・結合する列」だけを公開する、という規律が重要です。
具体例:どの列を公開するか
たとえば融資審査のようなケースを考えます。一覧画面で「ステータス」「担当者」「申込日」「金額」で絞り込み・並べ替えをし、顧客 ID でマスタと結合する——この 5 つは公開列にし、検索頻度の高いものにはインデックスを張ります。
一方、審査時の詳細コメント、スコアリングの中間計算値、画面表示専用のラベルなどは、レポートで絞り込む対象ではないので BLOB のままにします。そして、1 件の申込にぶら下がる「保証人明細(Page List)」を保証人氏名で検索したい要件が出てきたら、そこだけ Declare Index でインデックステーブルを作る。こうして「公開列」「Declare Index」「BLOB のまま」を役割で振り分けるのが実務の設計です。
よくある失敗
- 頻繁にフィルタする列にインデックス(あるいは公開)が無い。 一覧のたびに BLOB 展開やフルスキャンが走り、「なぜかレポートだけ遅い」状態になります。まず「どの列で絞り込んでいるか」を洗い出し、そこを公開+インデックス化するのが定石です。
- 逆に、使わない列を大量に公開している。 「あとで使うかも」で片っ端から最適化した結果、テーブルが横に広がり、更新のたびに全公開列とインデックスを書き込む羽目になります。公開は検索・レポート・結合で実際に使う列に絞ります。
- Page List をスカラー列にしようとして詰まる。 繰り返し構造は単純な公開では扱えません。明細レベルの検索が要るなら Declare Index に切り替えます。
- 後から公開した列は、既存行が埋まるまでにタイムラグがある。 これは特に見落とされがちです。データが既にある状態でプロパティを公開すると、Property Optimization(Optimize for reporting)ツールは新しい列を作成したうえで、既存インスタンスの値を BLOB から抽出して埋めるバックグラウンド処理を自動的に開始します。ただしこの処理は件数によっては数分以上かかり、完了するまで既存行の新しい列は NULL のままで、そのプロパティを使う計算やレポートが不完全・不正確になり得ます(進捗は列ポピュレーションのジョブ状況で確認できます)。ツールを介さずスキーマ変更などで列だけ追加した場合は、ポピュレート処理を別途自分で走らせる必要があります。いずれにせよ「公開した直後は古いケースがレポートに正しく出てこない」ことがあるため、反映完了を見届けてください(ツール名・手順は Pega のバージョンによって異なるため、利用中の版の公式ドキュメントで確認してください)。
まとめ
- Pega はケースデータ全体を圧縮 BLOB(
pzPVStream)に格納し、公開(最適化)したプロパティだけが物理列として SQL から扱える - 公開すべきは、レポート/検索/SQL でフィルタ・ソート・結合に使う列だけ。使わない値は BLOB のまま残す
- スカラーにできない埋め込みページ・Page List の値は Declare Index で別テーブル(
Index-クラス)にする - 公開列とインデックスは読みを速くするが書き込みと更新を重くする。過剰公開・過剰インデックスは更新性能を削る
- 後から公開した列は、既存行が埋まるまでにタイムラグがある。Property Optimization ツールが既存行を BLOB から埋めるバックグラウンド処理を自動で開始するが、完了するまで既存行は NULL のまま。反映完了を見届ける(手順は版により異なる)
公開列とインデックスの設計は、レポート性能とデータ更新性能のバランスそのものです。設計の初期に「この列は SQL で絞り込むか?」を一つずつ言語化しておくだけで、後工程での性能問題と作り直しを大きく減らせます。
関連リンク
関連記事
Pega 宣言的処理のコスト設計|前方連鎖と後方連鎖の使い分け
Declare Expression は便利だが、前方連鎖のカスケードは1つのプロパティ変更が広範な再計算を引き起こす。宣言的処理は「書けば動く」半面、実行コストが見えにくい。本記事は前方連鎖と後方連鎖、宣言的と手続き的の境界線を、性能と保守性の観点で整理する。
記事を読むPega Insights と Report Definition の使い分け|セルフサービス分析と運用レポートの線引き
「レポートは Report Definition で作るべきか、Insights でユーザーに任せるべきか」——ダッシュボード設計で必ず出る分岐です。統制と再利用が要る定型レポートはルール化し、アドホックな探索はセルフサービスに開く、が基本方針。本記事では両者のガバナンス差とデータソースの前提から、線引きの判断軸を示します。
記事を読むPega 監査証跡設計:フィールド監査・履歴・セキュリティ監査の使い分け
「何を、どこまで監査するか」は Pega のセキュリティ設計で最も判断が割れるテーマです。フィールド監査・ケース履歴・セキュリティイベントの使い分けと、監査のかけ過ぎが招く性能・容量問題の回避策を、LSA の視点で解説します。
記事を読む