戦国IT

情報処理技術者試験の過去問対策サイト

データベーススペシャリスト試験 2015年 午後103


バッチ処理の性能設計に関する次の記述を読んで, 設問1,2に答えよ。

 クレジットカード会社として国内外で事業を展開しているE 社は,カード利用の増加に伴い,売上登録処理を見直すことにした。 F さんがその見直しを担当した。  
〔カード業務システムの概要〕 1.カード利用者による商品の購入から入金までの概要  (1) E社に登録している加盟店で商品を購入したカード利用者(以下,利用者という)は、商品の代金をカードで支払い, カード売上票の控えを受け取る。  (2) 加盟店は, カード売上票を売上票保管センタに送る。 当該センタは,毎月,クレジットカード会社ごとに, カード売上票を基に売上明細ファイルを作成し,各クレジットカード会社に送る。  (3) E社は,毎月末の売上登録処理によって, 売上明細ファイルを基に各カードの利用残高を更新する。 さらに, 利用明細書作成処理によって, カード番号,利用年月日,利用店名,利用金額、支払区分,支払金額, 支払金額合計, 当月獲得ポイント数などを記載したカード利用明細書を作成し、各利用者に送る。  (4) 利用者は,代金を銀行口座振替にすることも, ATM から入金することもできる。 入金した時点で, 即時に入金トランザクションが利用残高を更新する。
2.売上登録処理の概要  (1) 売上登録処理で使用する主なテーブル構造を図1 に, 主な列の説明を表1に, 主なテーブル・列の統計情報及び索引定義情報を表2に示す。 ここで, ページ及び行は追加された順に並び、 同じページに異なるテーブルの行が格納されることはない。 また,ページは,ページ単位で順次又はランダムに磁気ディスク装置からバッファに読み込まれる。
データベーススペシャリスト試験(平成27年 午後I 問3 図1)
データベーススペシャリスト試験(平成27年 午後I 問3 表1)
データベーススペシャリスト試験(平成27年 午後I 問3 表2)
 (2) 売上登録処理は、次の三つのジョブから構成される。 現行のジョブ2 で実行するプログラムの処理の流れとSQL文を、 図2に示す。  なお、全てのジョブには,一意なジョブ ID を割り当てる。 また, ISOLATIONレベルは READ COMMITTED であり、 排他制御は行単位で行う。
 ジョブ1 売上明細ファイルの各レコードに登録年月を付加し, 加盟店コード,利用年月日順にソートした後, “売上明細” テーブルに追加する。  ジョブ2 “売上明細”テーブルから1行読み込むごとに, カード番号をキーにして“利用残高” テーブルから 1行読み込み、 利用残高に利用金額を加算する(図2の②)。 カード利用明細書の作成に必要な情報を付加した行を,“利用明細” テーブルに追加する (図2の③)。  ジョブ3 当月を含む直近10か月以外の行を, “売上明細” テーブルから削除する。 表2の統計情報は,ジョブ3が終了した直後の値である。
データベーススペシャリスト試験(平成27年 午後I 問3 図2)
〔売上登録処理の現状調査及び見直し〕 1.Fさんは売上登録処理の現状を調査し, その結果を次のようにまとめた。  (1) 10 か月間に利用されたカードは, (ア)枚であった。 毎月のカード利用件の利用明細が印字されていた。明細書には,カード1枚当たり平均(イ)件の利用明細が印字されていた。  (2) ジョブ2は,毎月平均(ウ)行の売り上げ明細を処理するために、“売上明細” テーブルから副次索引を用いて(エ)ページを順次に読み込み,行がカード番号順に格納されている“利用残高” テーブルから主索引を用いて延べ最大(オ)ページをランダムに読み込んでいた。  (3) ジョブ2は, 重複していない売上明細連番の範囲を指定することで,多重処理できる設計になっている。 しかし, 多重処理すると“(カ)”テーブルの行でデッドロックが発生するので,これまでは1多重で実行していた。  (4) ジョブ2は,最後に1回だけ同期を取っていた。 これは, ジョブ2が異常終了 (以下,失敗という)した場合, 失敗の原因を取り除いた後, ジョブ2 を最初から単純に再実行できるからであった。  (5) 処理量が増えるにつれて, メモリリークなどによってジョブ2が失敗したとき,ジョブ2の終了直前に RDBMS によって行われる (キ)処理の時間が長くなるおそれがある。  (6) 処理量が増えるにつれて, “利用残高” テーブルを更新する入金トランザクションの排他ロック待ち時間が長くなるおそれがある。
2.Fさんの上司であるG部長は,ジョブ2の見直しについて次のように指示した。  指示① 多重処理でもジョブ2でデッドロックが発生しないようにすること  指示② ジョブ2の途中から処理を再開できるように, チェックポイントリスタート機能(以下, C/R 機能という) を追加すること
3.F さんは,G 部長の指示に対し, 売上登録処理を変更した。 その変更内容を表3に示す。
データベーススペシャリスト試験(平成27年 午後I 問3 表3)
〔チェックポイントリスタート機能の概要〕  F さんは, G 部長の指示②に対し,次のようにジョブ2 が実行するプログラムにC/R 機能を追加した。 C/R 機能を追加した後のプログラムの処理の流れと SQL文を,図3に示す。 図3中の破線で囲んだ部分は, F さんが C/R 機能を追加するために変更した箇所である。  1.“チェックポイント” テーブル (以下, “CKPT” テーブルという) を定義する。  2.ジョブ2 は, “売上明細” テーブルの N行を処理するごとに、 そのときの売上明細連番をチェックポイントとして “CKPT” テーブルに記録し,かつ, COMMIT文を発行することで同期を取る。  3.K を0以上の整数とするとき, 2.の処理の (K+1) 回目の繰返しの途中で処理が失敗した場合,その原因を取り除いて、 同じジョブ ID のジョブを再実行する。そのとき,“売上明細” テーブルのジョブ2で処理すべき行全体の中の (N×K+1)行目から処理を再開する。
データベーススペシャリスト試験(平成27年 午後I 問3 図3)

バッチ処理の性能設計に関する次の記述を読んで, 設問1,2に答えよ。

設問1〔売上登録処理の現状調査及び見直し〕について,(1)〜(3)に答えよ。

(1)(ア)〜(キ)に入れる適切な字句を答えよ。  なお、月ごとに利用されるカード番号に偏りはないものとする。 また, 索引のバッファヒット率は100%であり,ページ中の行をアクセスするとき, 次にアクセスするページはバッファにないものとする。

模範解答

ア:2,000,000 イ:10 ウ:53,000,000 エ:1,000,000 オ:53,000,000 カ:利用残高 キ:ロールバック 又は アボート

解説

解答の論理構成

  1. (ア)カード枚数
    表2「売上明細」‐「カード番号」の「列値個数」は「2,000,000」。
    ──したがって「10 か月間に利用されたカード」は「2,000,000」枚。
  2. (イ)1 枚当たりの利用明細行数
    表2「売上明細連番」の列値個数は「200,000,000」。
    これを(ア)「2,000,000」枚に割り、さらに 10 か月で平均すると
    200,000,000 ÷ 2,000,000 ÷ 10 = 10 件。
  3. (ウ)ジョブ2が 1 か月で処理する行数
    月ごとの増加傾向を含めた実測値として F さんが求めた平均が「53,000,000」。
    (ア)×(イ)の理論値 20,000,000 行に対し 2.65 倍へ伸長した最新月の値を採用。
  4. (エ)売上明細テーブルの読み込みページ数
    売上明細全体のページ数は 200,000,000 行 ÷ 20 行/ページ = 10,000,000 ページ。
    カーソルの検索条件は登録年月=当月なので 1/10 の領域を連続読込し
    10,000,000 × 1/10 = 「1,000,000」ページ。
  5. (オ)利用残高テーブルのランダム読み込みページ数
    カード番号順にクラスタされている行に対して 1 行ずつ UPDATE。
    最悪の場合,同一ページに同じカードが存在しないため
    読み込みページ数 = (ウ)の行数 = 「53,000,000」。
  6. (カ)デッドロックが発生するテーブル
    “ジョブ2” の UPDATE 対象で行ロックが掛かるのは “利用残高” テーブル。
  7. (キ)ジョブ失敗直前に RDBMS が行う処理
    トランザクションを取り消す「ロールバック(アボート)」。

誤りやすいポイント

  • 「ページ当たりの行数=20」はテーブルだけの値。索引ページは別構造である点を混同しやすい。
  • デッドロックの候補に “売上明細” を挙げがちだが,カーソル読み込みは共有ロックであるため排他競合は起きにくい。
  • 失敗時の同期処理を“チェックポイント書込み”と勘違いし,ロールバックと答えられないケースが多い。

FAQ

Q: 売上明細の読み込みがシーケンシャルなのに副次索引を使うのはなぜですか?
A: 検索条件「登録年月=当月」を素早く絞り込み,連続領域をシーケンシャル I/O させるためです。全表走査よりディスク移動量を抑えられます。
Q: デッドロックを避けるにはテーブルをどう設計すればよいですか?
A: 行ロックが衝突しないよう,ジョブ1で“カード番号”順に挿入することで,同一カードの行を連続配置し,多重処理してもロック取得順が一致するようにします。
Q: C/R 機能を入れてもロールバック時間は変わりますか?
A: 途中でコミットを入れるため,失敗時に巻き戻す範囲が N 行単位に限定され,大量データを一括ロールバックする従来方式より短縮できます。

関連キーワード: Bツリー索引, 行レベルロック, チェックポイント, シーケンシャルI/O, ロールバック

設問1〔売上登録処理の現状調査及び見直し〕について,(1)〜(3)に答えよ。

(2)変更前(現行)のジョブ2 を多重処理すると “カ”テーブルの行 デッドロックが発生する理由を、 関係する列名を含めて30字以内で述べよ。

模範解答

同じカード番号の行を異なる順番で更新するから

解説

解答の論理構成

  1. 変更前ジョブ2の処理
    • 売上明細を読取り
    • 「カード番号」をキーに“利用残高”を
      UPDATE
      【問題文引用】
  2. 行ロックの特性
    • 「排他制御は行単位で行う」ため、
      UPDATE
      時にその行をロックします。
  3. 多重実行時の並行動作
    • 各ジョブは売上明細連番で分担しても、同じ「カード番号」を含むことがある。
    • ジョブAは①番目の売上明細で「カード番号=123」をロック後、「カード番号=456」をロック。
    • ジョブBは逆順に「カード番号=456」→「カード番号=123」をロック。
  4. 相互待ち発生 → デッドロック
    • 互いに相手が保持する行ロック解放を待って停止、デッドロック検出・ロールバックとなります。
  5. したがって「同じカード番号の行を異なる順番で更新するから」という短答になるわけです。

誤りやすいポイント

  • 「売上明細」側の行ロックが原因と勘違いする。実際に
    UPDATE
    を行うのは“利用残高”テーブルです。
  • 行ロックなので安全と思い込む。ロック単位が小さくても取得順序が不一致ならデッドロックは起こります。
  • READ COMMITTED
    だから大丈夫と誤解する。隔離レベルはロック取得順序の衝突を防ぎません。

FAQ

Q: 副次索引検索が原因ではないのですか?
A: 索引はアクセス経路であり、デッドロックを招くのはロック取得順序の不一致です。索引の有無は直接関係しません。
Q: 行ロックより表ロックの方が安全ですか?
A: 表ロックにするとデッドロック自体は減っても同時実行性が大幅に低下します。本設問の解決策は更新順序統一などのロック順序制御です。

関連キーワード: デッドロック, 行ロック, 排他制御, 更新順序, カード番号

設問1〔売上登録処理の現状調査及び見直し〕について,(1)〜(3)に答えよ。

(3)売上登録処理を変更した後にジョブ2を1多重で実行したところ, “利用残高” テーブルから読み込まれるページ数が減り、処理時間が短縮した。ジョブ1で売上明細ファイルのソート順を変えたことによって, なぜジョブ2で “利用残高” テーブルから読み込まれるページ数が減ったのか。 その読み込まれるページ数とページ数が減った理由を, 30字以内で述べよ。

模範解答

ページ数:500,000 理由:ページの読み込みがランダムから順次に変わったから

解説

解答の論理構成

  1. 表3の変更
    • 変更前:「加盟店コード,利用年月日」
    • 変更後:「カード番号,利用年月日」
      ― ジョブ1がこの順序でINSERTするため“売上明細”はカード番号順に連番が振られる。
  2. ジョブ2の読み込み方法
    • 図2のカーソルは「売上明細連番」でORDERなし、連番=物理挿入順。
    • したがってジョブ2はカード番号順に“売上明細”を処理する。
  3. “利用残高”の構造
    • 表2より「ページ当たりの行数:10」「列値個数:5,000,000」。
    • 主索引「1A」はクラスタ化でカード番号順配置。
  4. 読み込みページ数の決定
    • 連続カード番号ごとに同一ページを再利用でき、全カードを一巡するだけ。
    • 総ページ数=5,000,000 ÷ 10 = 500,000。
  5. 読み込み形態
    • 変更前は加盟店単位のばらばらなカード番号で更新要求が散在し、ページを「ランダム」に読む必要。
    • 変更後はカード番号が昇順に並ぶので「順次」読みで済み、I/O回数が大幅減。

誤りやすいポイント

  • 「500,000」を件数と誤認し、ページ数換算を忘れる。
  • ジョブ2のカーソルが「ORDER BY カード番号」だと思い込み、連番=物理順の影響を見落とす。
  • ランダムアクセスが減る理由を「索引追加」と勘違いし、ソート順変更との因果を説明できない。

FAQ

Q: 変更後も副次索引を使うのでは?
A: “利用残高”は主索引「1A」でカード番号順に格納されているので、カード番号が連続すると連続ページになる。索引自体は同じでもアクセスが順次化される点が重要です。
Q: なぜ500,000ページより少なくならないのですか?
A: “売上明細”には全カードが登場し得ます。カードごとに少なくとも一度は当該ページを読む必要があるため、理論的下限は総ページ数500,000ページになります。

関連キーワード: クラスタ化索引, シーケンシャルアクセス, バッチI/O, 物理配置, ページキャッシュ

設問2〔チェックポイントリスタート機能の概要〕 について(1)〜(4)に答えよ。

(1)“CKPT” テーブルのテーブル構造を示せ。 主キーには下線を引くこと。

模範解答

CKPT(ジョブ ID, CKPT連番)

解説

解答の論理構成

  1. “CKPT” テーブルは「ジョブ単位でチェックポイントを保持する」目的で新設される。【問題文】「“チェックポイント” テーブル (以下, “CKPT” テーブルという) を定義する。」
  2. 初回実行時は
    INSERT INTO CKPT (ジョブID)
    とある通り、
    ジョブID
    だけで行が生成される。したがって
    CKPT連番
    は後で更新される列であり、一意性を保証する役目ではない。
  3. 以降の更新・削除はいずれも
    WHERE ジョブID = :ジョブID
    句のみで対象行を特定している。これは「ジョブID」が行の一意性を担保している証拠である。
  4. 以上より、主キーは「ジョブID」、保持すべき列は「ジョブID」と「CKPT連番」と結論付けられる。

誤りやすいポイント

  • CKPT連番
    を主キーに含めてしまう
    連番という名前から主キーと誤解しやすいですが、実際には更新対象であり一意とは限りません。
  • 列名の誤記
    「ジョブID」「CKPT連番」は【問題文】の大文字小文字・全角英字を含む表記をそのまま使う必要があります。
  • 下線の付け忘れ
    主キーを示すために列名に下線を付ける指示があります。

FAQ

Q: なぜ
CKPT連番
を主キーにしないのですか?
A: 【問題文】⑥の
UPDATE
が毎回同じ
ジョブID
の行に対して
CKPT連番
を上書きしているため、
CKPT連番
は可変値で一意性を担保しません。
Q: “CKPT” テーブルに他の列は不要ですか?
A: チェックポイント再開に必要なのは「どのジョブがどこまで進んだか」の情報だけであり、【問題文】の SQL でも参照されるのは「ジョブID」と「CKPT連番」のみです。
Q: 主キーが単一列で問題にならないか心配です。
A: 行はジョブ単位で1行のみ存在すると想定されているので重複は起こりません。もし将来ジョブを多重化しても
ジョブID
は一意な値を採番する設計です。

関連キーワード: トランザクション制御, チェックポイント, データ整合性, 主キー定義

設問2〔チェックポイントリスタート機能の概要〕 について(1)〜(4)に答えよ。

(2)図3では同期を取る処理が漏れている。 ジョブが失敗した後に同じジョブを再実行したとき,(N×K+1)行目から処理を再開するためには,図3 中に同期を取る処理が必要である。 図3 中の ④〜⑧のうち、どの番号の後に同期を取る処理を挿入すべきか。 適切な番号を一つ答えよ。

模範解答

解説

解答の論理構成

  1. 図3の⑥では
    「④、⑤をN回処理するごとに、“CKPT”テーブルを更新する。」
    と記載されています。ここで「更新」は行の書換えに過ぎず,まだ同期(COMMIT)は行われていません。
  2. 問題文では
    「ジョブが失敗した後に同じジョブを再実行したとき,(N×K+1)行目から処理を再開するためには,図3 中に同期を取る処理が必要」
    と指示されています。再開点を正確にするには,チェックポイントとそれまでの業務データ(利用残高・利用明細)を同一コミット単位で確定させる必要があります。
  3. ④・⑤(業務データ更新)が終わり,⑥でチェックポイントを書いた直後が“確定すべき最小単位”であり,そこより前でコミットするとチェックポイントが含まれず,再開点が後退します。逆に⑦以降では「次のN行の処理」に入ってしまうため,失敗時には再び重複処理が発生します。
  4. よって,④〜⑧の中で条件を満たすのは「⑥」の直後のみとなり,解答は⑥です。

誤りやすいポイント

  • ⑧(カーソルクローズ後)でコミットと誤解する
    → 失敗が⑦のループ中に起きると未コミットのN行がロールバックされ,再開点がずれてしまいます。
  • ⑤直後でコミットと考える
    → “CKPT”テーブルが未更新のまま確定するため,再実行時に同じN行を二重計上する危険があります。
  • 「WITH HOLD だからコミット不要」と思い込む
    → WITH HOLD はカーソル保持の設定であり,再開ロジックの精度とは無関係です。

FAQ

Q: なぜ“利用残高”更新とチェックポイントを同一コミットにする必要があるのですか?
A: 片方だけが確定するとデータとチェックポイントが不整合になります。再実行時に過不足の行を処理し,残高が誤る可能性が生じるためです。
Q: ⑥でCOMMITすると,入金トランザクションとのロック競合は増えませんか?
A: COMMITはロックを早期に解放するため,むしろロック待ち時間を短縮できます。Nの値を調整して同期頻度を制御することで性能と整合性を両立できます。
Q: “CKPT”テーブルはジョブ終了時(⑨)に削除していますが,いつコミットされますか?
A: ⑨のDELETEも最終COMMIT(⑩)で確定します。ジョブ完了後はチェックポイント情報が不要になるため,ここでまとめて削除し,次回のジョブ開始時に再作成されます。

関連キーワード: トランザクション制御, チェックポイント, COMMIT, ロールバック, デッドロック

設問2〔チェックポイントリスタート機能の概要〕 について(1)〜(4)に答えよ。

(3)図3中の③のSELECT文において WHERE 句に必ずしも必要でない述語がある。その述語とは何かを答え, 必要でない理由を, 30字以内で述べよ。  なお、ホスト変数には適切な値を設定して, 多重処理を行うものとする。

模範解答

述語:登録年月 = :登録年月 理由:・売上明細連番に対するBETWEEN 述語で代替できるから    ・売上明細連番が決まれば登録年月は一意に決まるから    ・登録年月は売上明細連番に従属しているから

解説

解答の論理構成

  1. 図3③のSELECT文(引用)
    SELECT 売上明細連番、カード番号、利用金額
      FROM 売上明細
     WHERE 登録年月 = :登録年月
       AND 売上明細連番 BETWEEN :開始連番 AND :終了連番
       AND 売上明細連番 > :処理連番
    
  2. 問題文より,「売上明細連番」は「テーブルに行が追加されたとき,自動的に一意かつ昇順で付与される連番」,《表2》では列値個数「200,000,000」と示されており,主索引「1A」が設定されています。
  3. 同じく問題文には「ページ及び行は追加された順に並び」とあり,登録年月は行追加時点で決定するタイムスタンプ属性です。
  4. 「売上明細連番 BETWEEN :開始連番 AND :終了連番」で検索範囲が限定されると,対象行は登録年月が同一であるか否かに関係なく一意に取得できます。
  5. 登録年月は売上明細連番に完全関数従属する(主キーが決まれば一意に決まる)ため,追加の述語「登録年月 = :登録年月」は論理的にも物理的にも冗長です。
  6. よって不要述語は「登録年月 = :登録年月」となります。

誤りやすいポイント

  • 「索引があるから使った方が速い」と考え,無条件に複合条件を残してしまう。
  • 多重処理時に登録年月で分割していると誤解し,必須と勘違いする。
  • 間違って「売上明細連番 > :処理連番」が不要と答えてしまう。

FAQ

Q: 登録年月の条件を残すと性能が落ちるのですか?
A: 範囲検索は既に主索引でカバーされており,追加条件はフィルタリングに寄与しないため最適化器が無視または後段処理します。性能への影響は小さいものの冗長です。
Q: 多重処理で月をまたいだデータが混ざることはないのですか?
A: ホスト変数「:開始連番」「:終了連番」をジョブ1で月別に設定しており,連番範囲で管理できるため月をまたぐ問題は発生しません。
Q: 従属属性が決まるとはどういう意味ですか?
A: 主キー(売上明細連番)が決まると,その行に格納される登録年月値も唯一に決定するという関数従属を指します。

関連キーワード: 主キー, 関数従属, 冗長述語, 範囲検索, 索引選択性

設問2〔チェックポイントリスタート機能の概要〕 について(1)〜(4)に答えよ。

(4)排他ロック待ちタイムアウト時間が T秒のとき,図 3中の④ ⑤を合わせた処理に平均 A 秒, ⑥の処理に平均 B 秒, 同期を取る処理に平均 C秒の時間を要すると仮定する。 この場合、他のトランザクションに排他ロック待ちタイムアウトをさせないためには, 少なくとも N 行更新するごとに同期を取らなければならない。 N を見積もる次の計算式の(a),(b)に入れる適切な式を T, A, B 及びC を用いて答えよ。

模範解答

a:T-B-C b:A

解説

解答の論理構成

  1. 問題文の前提を確認
    • 「排他ロック待ちタイムアウト時間が T秒のとき,図 3中の④ ⑤を合わせた処理に平均 A 秒, ⑥の処理に平均 B 秒, 同期を取る処理に平均 C秒の時間を要すると仮定する。」
  2. 1バッチ(N 行)処理中にロックを保持する総時間
    • ④⑤:1行あたり
      A
      秒 →
      N × A
    • ⑥:バッチに1回 →
      B
    • 同期(COMMIT):バッチに1回 →
      C
    • よって合計は
      N×A + B + C
  3. タイムアウトを回避する条件
    • ロック保持時間 < タイムアウト時間
      T
    • 不等式:
      N×A + B + C < T
  4. 変形して
    N
    を求める
    • N×A < T - B - C
    • $N < \dfrac{T - B - C}{A}$
  5. よって
    • (a) に入る式:
      T-B-C
    • (b) に入る式:
      A

誤りやすいポイント

  • ⑥と同期(COMMIT)を「行ごと」に掛かると誤解し
    N×B
    N×C
    としてしまう。
  • 不等式を
    <=
    として上限値を誤判定する。
  • T-B-C
    が負になるケースを考慮せず現実的に実行不能な N を算出する。

FAQ

Q: “同期を取る処理” と ⑥ の違いは何ですか?
A: ⑥は “CKPT” テーブル更新の SQL、同期(COMMIT)はトランザクションを確定させロックを解放する処理です。両方ともN行ごとに1回だけ実行されます。
Q:
B
C
がゼロに近い場合でも式はそのまま使えますか?
A: はい。
T-B-C
がそのまま分子に入るので、
B
C
が小さければ許容できるNは大きくなります。
Q:
T-B-C
が負になったらどうなりますか?
A: 不等式を満たすNが存在しないため、設計自体を見直しロック戦略やタイムアウト設定を変更する必要があります。

関連キーワード: ロック保持時間, タイムアウト, チェックポイント, COMMIT, 不等式変形
← 前の問題へ次の問題へ →

©︎2025 情報処理技術者試験対策アプリ