データベーススペシャリスト 2015年 午後1 問03
バッチ処理の性能設計に関する次の記述を読んで、設問1,2に答えよ。
クレジットカード会社として国内外で事業を展開しているE社は、カード利用の増加に伴い、売上登録処理を見直すことにした。 Fさんがその見直しを担当した。
〔カード業務システムの概要〕
1.カード利用者による商品の購入から入金までの概要
(1) E社に登録している加盟店で商品を購入したカード利用者(以下、利用者という)は、商品の代金をカードで支払い、カード売上票の控えを受け取る。
(2) 加盟店は、カード売上票を売上票保管センタに送る。 当該センタは、毎月、クレジットカード会社ごとに、カード売上票を基に売上明細ファイルを作成し、各クレジットカード会社に送る。
(3) E社は、毎月末の売上登録処理によって、売上明細ファイルを基に各カードの利用残高を更新する。 さらに、利用明細書作成処理によって、カード番号、利用年月日、利用店名、利用金額、支払区分、支払金額、支払金額合計、当月獲得ポイント数などを記載したカード利用明細書を作成し、各利用者に送る。
(4) 利用者は、代金を銀行口座振替にすることも、ATMから入金することもできる。 入金した時点で、即時に入金トランザクションが利用残高を更新する。
2.売上登録処理の概要
(1) 売上登録処理で使用する主なテーブル構造を図1に、主な列の説明を表1に、主なテーブル・列の統計情報及び索引定義情報を表2に示す。 ここで、ページ及び行は追加された順に並び、同じページに異なるテーブルの行が格納されることはない。 また、ページは、ページ単位で順次又はランダムに磁気ディスク装置からバッファに読み込まれる。



(2) 売上登録処理は、次の三つのジョブから構成される。 現行のジョブ2で実行するプログラムの処理の流れとSQL文を、図2に示す。
なお、全てのジョブには、一意なジョブIDを割り当てる。 また、ISOLATIONレベルはREAD COMMITTEDであり、排他制御は行単位で行う。
ジョブ1 売上明細ファイルの各レコードに登録年月を付加し、加盟店コード、利用年月日順にソートした後、“売上明細” テーブルに追加する。
ジョブ2 “売上明細”テーブルから1行読み込むごとに、カード番号をキーにして“利用残高” テーブルから1行読み込み、利用残高に利用金額を加算する(図2の②)。 カード利用明細書の作成に必要な情報を付加した行を、“利用明細” テーブルに追加する (図2の③)。
ジョブ3 当月を含む直近10か月以外の行を、“売上明細” テーブルから削除する。 表2の統計情報は、ジョブ3が終了した直後の値である。

〔売上登録処理の現状調査及び見直し〕
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に示す。

〔チェックポイントリスタート機能の概要〕
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)行目から処理を再開する。
設問1:〔売上登録処理の現状調査及び見直し〕について、(1)〜(3)に答えよ。
問題文を見る(1)(ア)〜(キ)に入れる適切な字句を答えよ。
なお、月ごとに利用されるカード番号に偏りはないものとする。 また、索引のバッファヒット率は100%であり、ページ中の行をアクセスするとき、次にアクセスするページはバッファにないものとする。
模範解答
ア:2,000,000
イ:10
ウ:20,000,000
エ:1,000,000
オ:20,000,000
カ:利用残高
キ:ロールバック 又は アボート
解説
解答の導き方
(ア)
表2に「売上明細 の 列名 カード番号 列値個数2,000,000」とある点を使います。問題文の文言「10か月間に利用されたカードは、(ア)枚であった。」はこの統計値を指すので、(ア)は表2の値と一致します。
したがって、(ア) = 2,000,000。
したがって、(ア) = 2,000,000。
(イ)
売上明細テーブル全体について、表2の「売上明細連番 列値個数200,000,000」は直近10か月分の行数であることが本文に明示されています(「表2の統計情報は、ジョブ3が終了した直後の値である」)。よって10か月分の売上明細行数は です。これを(ア)のカード枚数 で割ると、1枚のカードが10か月間に持つ平均利用明細件数は
件(=10か月分)となります。問題は月ごとの平均件数を問うているので、これを10か月で割り、
となります。
したがって、(イ) = 10。
したがって、(イ) = 10。
(ウ), (エ), (オ)
まず (ウ) は、ジョブ2が毎月処理する売上明細の行数です。表2の売上明細の行数 200,000,000 は直近10か月分なので、1か月当たりの平均は
行です。
したがって、(ウ) = 20,000,000。
行です。
したがって、(ウ) = 20,000,000。
次に (エ)(売上明細テーブルを副次索引で順次に読み込むときのページ数)は、売上明細テーブルの総行数 が直近10か月分であることから、1か月分の行数は
行です。売上明細の「ページ当たりの行数」は表2の値で20行/ページなので、1か月分に読み込むページ数は
ページです。条件に「索引のバッファヒット率は100%であり、ページ中の行をアクセスするとき、次にアクセスするページはバッファにない」とあるため、順次読み込みではページ単位でこの数だけI/Oが発生すると考えます。
したがって、(エ) = 1,000,000。
したがって、(エ) = 1,000,000。
最後に (オ)(利用残高テーブルを主索引で延べ最大何ページランダム読み込みするか)は、図2の処理フローに従い「売上明細の1行を読み込むごとに利用残高テーブルを更新する(UPDATE)」とある点を使います。すなわち、売上明細1行につき利用残高テーブルへ1件の更新を行い、その更新は主索引で目的行を特定して行われます。問題の前提で「索引のバッファヒット率は100%」だが「ページ中の行をアクセスするとき、次にアクセスするページはバッファにない」とあるため、各UPDATEは対応するテーブルページの読み込み(ランダムI/O)を生じます。よって、延べランダムページ読み込み回数は処理した売上明細行数と等しくなります。(ウ) = 20,000,000 なので、
(オ) = (ウ) = 20,000,000。
(オ) = (ウ) = 20,000,000。
(要点まとめ:売上明細の1か月分は 行、順次読み込みページ数は 、利用残高へのランダム読み込み回数は「売上明細1行につき1回のUPDATE→1回のページ読み込み」として (ウ) に等しいと判断します。)
(カ)
本文に「多重処理すると“(カ)”テーブルの行でデッドロックが発生する」とあり、ジョブ2の処理で繰り返しUPDATEを行っているのは「利用残高」テーブルです(図1・図2の処理から明らか)。実際、各売上明細行ごとに「利用残高」をカード番号で更新しているため、並列に処理すると行ロックの競合や相互待ちによるデッドロックが発生します。
したがって、(カ) = 利用残高。
したがって、(カ) = 利用残高。
(キ)
問題は「ジョブ2は、最後に1回だけ同期を取っていた。これは、ジョブ2が異常終了した場合、…ジョブ2を最初から単純に再実行できるからであった。」と説明しており、その直後に「ジョブ2が失敗したとき、ジョブ2の終了直前にRDBMSによって行われる (キ)処理の時間が長くなるおそれがある。」とあります。トランザクション処理の観点で、失敗時にRDBMSが行う処理は未コミット更新を取り消すためのロールバック(アボート)です。大量の未コミット更新があるほどロールバックに時間がかかります。
したがって、(キ) = ロールバック 又は アボート。
したがって、(キ) = ロールバック 又は アボート。
以上により、空欄にはそれぞれ (ア) = 2,000,000、(イ) = 10、(ウ) = 20,000,000、(エ) = 1,000,000、(オ) = 20,000,000、(カ) = 利用残高、(キ) = ロールバック 又は アボート が入ります。
誤りやすいポイント
- 表2の「売上明細連番200,000,000」をそのまま「1か月分」と誤解する。表2はジョブ3直後の「直近10か月分」の合計であり、1か月分は である点を忘れないこと。
- 「延べページ数」と「実際に存在するページ数(ユニークページ数)」を混同する。問題文中の「延べ最大(オ)ページ」は延べ(合計の読み込み回数)を指すため、同一ページの複数回読み込みもカウントされる点に注意する。
- インデックスのバッファヒット率が100%であってもテーブルページのバッファを考慮しない前提があるため、インデックス探索自体が無コストでもテーブルページ読み込みは生じる点を見落としやすい。
- デッドロックの発生箇所は更新対象テーブル(利用残高)である点を見落とすと誤答になる。
FAQ
Q: (ウ) はどうして20,000,000になるのか?
A: 表2の売上明細の行数 200,000,000 は直近10か月分(ジョブ3が終了した直後の値)なので、1か月当たりの平均は 行です。
A: 表2の売上明細の行数 200,000,000 は直近10か月分(ジョブ3が終了した直後の値)なので、1か月当たりの平均は 行です。
Q: (エ) はどうして1,000,000ページになるのか?
A: 売上明細の直近10か月分の総行数が 、1か月分は 行、表2のページ当たり行数が20行/ページなので ページになります。副次索引で条件「登録年月」を指定して当月分の行を順次読み込む場合、このページ数だけ順次読み込みI/Oが発生します。
A: 売上明細の直近10か月分の総行数が 、1か月分は 行、表2のページ当たり行数が20行/ページなので ページになります。副次索引で条件「登録年月」を指定して当月分の行を順次読み込む場合、このページ数だけ順次読み込みI/Oが発生します。
Q: (オ) が (ウ) と等しい理由は?
A: 売上明細1行につき利用残高テーブルの該当行をUPDATEしているため、1行の処理ごとに1回の利用残高ページ読み込み(ランダムI/O)が必要になります。条件として「ページ中の行をアクセスするとき、次にアクセスするページはバッファにない」とあるため、各更新でページ読み込みが発生し、延べ読み込み回数は処理行数(ウ)に等しくなります。
A: 売上明細1行につき利用残高テーブルの該当行をUPDATEしているため、1行の処理ごとに1回の利用残高ページ読み込み(ランダムI/O)が必要になります。条件として「ページ中の行をアクセスするとき、次にアクセスするページはバッファにない」とあるため、各更新でページ読み込みが発生し、延べ読み込み回数は処理行数(ウ)に等しくなります。
関連キーワード: トランザクション管理、ロック、ロールバック、インデックス、バッファキャッシュ
設問1:〔売上登録処理の現状調査及び見直し〕について、(1)〜(3)に答えよ。
問題文を見る(2)変更前(現行)のジョブ2を多重処理すると “カ”テーブルの行でデッドロックが発生する理由を、関係する列名を含めて30字以内で述べよ。
模範解答
同じカード番号の行を異なる順番で更新するから
解説
解答の論理構成
- 変更前ジョブ2の処理
- 売上明細を読取り
- 「カード番号」をキーに“利用残高”を UPDATE【問題文引用】
- 行ロックの特性
- 「排他制御は行単位で行う」ため、UPDATE 時にその行をロックします。
- 多重実行時の並行動作
- 各ジョブは売上明細連番で分担しても、同じ「カード番号」を含むことがある。
- ジョブAは①番目の売上明細で「カード番号=123」をロック後、「カード番号=456」をロック。
- ジョブBは逆順に「カード番号=456」→「カード番号=123」をロック。
- 相互待ち発生 → デッドロック
- 互いに相手が保持する行ロック解放を待って停止、デッドロック検出・ロールバックとなります。
- したがって「同じカード番号の行を異なる順番で更新するから」という短答になるわけです。
誤りやすいポイント
- 「売上明細」側の行ロックが原因と勘違いする。実際に UPDATE を行うのは“利用残高”テーブルです。
- 行ロックなので安全と思い込む。ロック単位が小さくても取得順序が不一致ならデッドロックは起こります。
- READ COMMITTEDだから大丈夫と誤解する。隔離レベルはロック取得順序の衝突を防ぎません。
FAQ
Q: 副次索引検索が原因ではないのですか?
A: 索引はアクセス経路であり、デッドロックを招くのはロック取得順序の不一致です。索引の有無は直接関係しません。
A: 索引はアクセス経路であり、デッドロックを招くのはロック取得順序の不一致です。索引の有無は直接関係しません。
Q: 行ロックより表ロックの方が安全ですか?
A: 表ロックにするとデッドロック自体は減っても同時実行性が大幅に低下します。本設問の解決策は更新順序統一などのロック順序制御です。
A: 表ロックにするとデッドロック自体は減っても同時実行性が大幅に低下します。本設問の解決策は更新順序統一などのロック順序制御です。
関連キーワード: デッドロック、行ロック、排他制御、更新順序、カード番号
設問1:〔売上登録処理の現状調査及び見直し〕について、(1)〜(3)に答えよ。
問題文を見る(3)売上登録処理を変更した後にジョブ2を1多重で実行したところ、“利用残高” テーブルから読み込まれるページ数が減り、処理時間が短縮した。ジョブ1で売上明細ファイルのソート順を変えたことによって、なぜジョブ2で “利用残高” テーブルから読み込まれるページ数が減ったのか。 その読み込まれるページ数とページ数が減った理由を、30字以内で述べよ。
模範解答
ページ数:500,000
理由:ページの読み込みがランダムから順次に変わったから
解説
解答の論理構成
- 表3の変更
- 変更前:「加盟店コード、利用年月日」
- 変更後:「カード番号、利用年月日」
― ジョブ1がこの順序でINSERTするため“売上明細”はカード番号順に連番が振られる。
- ジョブ2の読み込み方法
- 図2のカーソルは「売上明細連番」でORDERなし、連番=物理挿入順。
- したがってジョブ2はカード番号順に“売上明細”を処理する。
- “利用残高”の構造
- 表2より「ページ当たりの行数:10」「列値個数:5,000,000」。
- 主索引「1A」はクラスタ化でカード番号順配置。
- 読み込みページ数の決定
- 連続カード番号ごとに同一ページを再利用でき、全カードを一巡するだけ。
- 総ページ数=5,000,000 ÷ 10 = 500,000。
- 読み込み形態
- 変更前は加盟店単位のばらばらなカード番号で更新要求が散在し、ページを「ランダム」に読む必要。
- 変更後はカード番号が昇順に並ぶので「順次」読みで済み、I/O回数が大幅減。
誤りやすいポイント
- 「500,000」を件数と誤認し、ページ数換算を忘れる。
- ジョブ2のカーソルが「ORDER BY カード番号」だと思い込み、連番=物理順の影響を見落とす。
- ランダムアクセスが減る理由を「索引追加」と勘違いし、ソート順変更との因果を説明できない。
FAQ
Q: 変更後も副次索引を使うのでは?
A: “利用残高”は主索引「1A」でカード番号順に格納されているので、カード番号が連続すると連続ページになる。索引自体は同じでもアクセスが順次化される点が重要です。
A: “利用残高”は主索引「1A」でカード番号順に格納されているので、カード番号が連続すると連続ページになる。索引自体は同じでもアクセスが順次化される点が重要です。
Q: なぜ500,000ページより少なくならないのですか?
A: “売上明細”には全カードが登場し得ます。カードごとに少なくとも一度は当該ページを読む必要があるため、理論的下限は総ページ数500,000ページになります。
A: “売上明細”には全カードが登場し得ます。カードごとに少なくとも一度は当該ページを読む必要があるため、理論的下限は総ページ数500,000ページになります。
関連キーワード: クラスタ化索引、シーケンシャルアクセス、バッチI/O, 物理配置、ページキャッシュ
設問2:〔チェックポイントリスタート機能の概要〕 について(1)〜(4)に答えよ。
問題文を見る(1)“CKPT” テーブルのテーブル構造を示せ。 主キーには下線を引くこと。
模範解答
CKPT(ジョブID、CKPT連番)
解説
解答の論理構成
- “CKPT” テーブルは「ジョブ単位でチェックポイントを保持する」目的で新設される。【問題文】「“チェックポイント” テーブル (以下、“CKPT” テーブルという) を定義する。」
- 初回実行時は INSERT INTO CKPT (ジョブID) とある通り、ジョブID だけで行が生成される。したがって CKPT連番 は後で更新される列であり、一意性を保証する役目ではない。
- 以降の更新・削除はいずれも WHERE ジョブID = :ジョブID 句のみで対象行を特定している。これは「ジョブID」が行の一意性を担保している証拠である。
- 以上より、主キーは「ジョブID」、保持すべき列は「ジョブID」と「CKPT連番」と結論付けられる。
誤りやすいポイント
- CKPT連番 を主キーに含めてしまう
連番という名前から主キーと誤解しやすいですが、実際には更新対象であり一意とは限りません。 - 列名の誤記
「ジョブID」「CKPT連番」は【問題文】の大文字小文字・全角英字を含む表記をそのまま使う必要があります。 - 下線の付け忘れ
主キーを示すために列名に下線を付ける指示があります。
FAQ
Q: なぜCKPT連番 を主キーにしないのですか?
A: 【問題文】⑥の UPDATE が毎回同じ ジョブID の行に対して CKPT連番 を上書きしているため、CKPT連番 は可変値で一意性を担保しません。
A: 【問題文】⑥の UPDATE が毎回同じ ジョブID の行に対して CKPT連番 を上書きしているため、CKPT連番 は可変値で一意性を担保しません。
Q: “CKPT” テーブルに他の列は不要ですか?
A: チェックポイント再開に必要なのは「どのジョブがどこまで進んだか」の情報だけであり、【問題文】のSQLでも参照されるのは「ジョブID」と「CKPT連番」のみです。
A: チェックポイント再開に必要なのは「どのジョブがどこまで進んだか」の情報だけであり、【問題文】のSQLでも参照されるのは「ジョブID」と「CKPT連番」のみです。
Q: 主キーが単一列で問題にならないか心配です。
A: 行はジョブ単位で1行のみ存在すると想定されているので重複は起こりません。もし将来ジョブを多重化しても ジョブIDは一意な値を採番する設計です。
A: 行はジョブ単位で1行のみ存在すると想定されているので重複は起こりません。もし将来ジョブを多重化しても ジョブIDは一意な値を採番する設計です。
関連キーワード: トランザクション制御、チェックポイント、データ整合性、主キー定義
設問2:〔チェックポイントリスタート機能の概要〕 について(1)〜(4)に答えよ。
問題文を見る(2)図3では同期を取る処理が漏れている。 ジョブが失敗した後に同じジョブを再実行したとき、(N×K+1)行目から処理を再開するためには、図3中に同期を取る処理が必要である。 図3中の ④〜⑧のうち、どの番号の後に同期を取る処理を挿入すべきか。 適切な番号を一つ答えよ。
模範解答
⑥
解説
解答の論理構成
- 図3の⑥では
「④、⑤をN回処理するごとに、“CKPT”テーブルを更新する。」
と記載されています。ここで「更新」は行の書換えに過ぎず、まだ同期(COMMIT)は行われていません。 - 問題文では
「ジョブが失敗した後に同じジョブを再実行したとき、(N×K+1)行目から処理を再開するためには、図3中に同期を取る処理が必要」
と指示されています。再開点を正確にするには、チェックポイントとそれまでの業務データ(利用残高・利用明細)を同一コミット単位で確定させる必要があります。 - ④・⑤(業務データ更新)が終わり、⑥でチェックポイントを書いた直後が“確定すべき最小単位”であり、そこより前でコミットするとチェックポイントが含まれず、再開点が後退します。逆に⑦以降では「次のN行の処理」に入ってしまうため、失敗時には再び重複処理が発生します。
- よって、④〜⑧の中で条件を満たすのは「⑥」の直後のみとなり、解答は⑥です。
誤りやすいポイント
- ⑧(カーソルクローズ後)でコミットと誤解する
→ 失敗が⑦のループ中に起きると未コミットのN行がロールバックされ、再開点がずれてしまいます。 - ⑤直後でコミットと考える
→ “CKPT”テーブルが未更新のまま確定するため、再実行時に同じN行を二重計上する危険があります。 - 「WITH HOLDだからコミット不要」と思い込む
→ WITH HOLDはカーソル保持の設定であり、再開ロジックの精度とは無関係です。
FAQ
Q: なぜ“利用残高”更新とチェックポイントを同一コミットにする必要があるのですか?
A: 片方だけが確定するとデータとチェックポイントが不整合になります。再実行時に過不足の行を処理し、残高が誤る可能性が生じるためです。
A: 片方だけが確定するとデータとチェックポイントが不整合になります。再実行時に過不足の行を処理し、残高が誤る可能性が生じるためです。
Q: ⑥でCOMMITすると、入金トランザクションとのロック競合は増えませんか?
A: COMMITはロックを早期に解放するため、むしろロック待ち時間を短縮できます。Nの値を調整して同期頻度を制御することで性能と整合性を両立できます。
A: COMMITはロックを早期に解放するため、むしろロック待ち時間を短縮できます。Nの値を調整して同期頻度を制御することで性能と整合性を両立できます。
Q: “CKPT”テーブルはジョブ終了時(⑨)に削除していますが、いつコミットされますか?
A: ⑨のDELETEも最終COMMIT(⑩)で確定します。ジョブ完了後はチェックポイント情報が不要になるため、ここでまとめて削除し、次回のジョブ開始時に再作成されます。
A: ⑨のDELETEも最終COMMIT(⑩)で確定します。ジョブ完了後はチェックポイント情報が不要になるため、ここでまとめて削除し、次回のジョブ開始時に再作成されます。
関連キーワード: トランザクション制御、チェックポイント、COMMIT, ロールバック、デッドロック
設問2:〔チェックポイントリスタート機能の概要〕 について(1)〜(4)に答えよ。
問題文を見る(3)図3中の③のSELECT文において WHERE 句に必ずしも必要でない述語がある。その述語とは何かを答え、必要でない理由を、30字以内で述べよ。
なお、ホスト変数には適切な値を設定して、多重処理を行うものとする。
模範解答
述語:登録年月 = :登録年月
理由:・売上明細連番に対するBETWEEN 述語で代替できるから
・売上明細連番が決まれば登録年月は一意に決まるから
・登録年月は売上明細連番に従属しているから
解説
解答の論理構成
-
図3③のSELECT文(引用)
sql SELECT 売上明細連番, カード番号, 利用金額 FROM 売上明細 WHERE 登録年月 = :登録年月 AND 売上明細連番 BETWEEN :開始連番 AND :終了連番 AND 売上明細連番 > :処理連番 -
問題文より、「売上明細連番」は「テーブルに行が追加されたとき、自動的に一意かつ昇順で付与される連番」、《表2》では列値個数「200,000,000」と示されており、主索引「1A」が設定されています。
-
同じく問題文には「ページ及び行は追加された順に並び」とあり、登録年月は行追加時点で決定するタイムスタンプ属性です。
-
「売上明細連番 BETWEEN :開始連番 AND :終了連番」で検索範囲が限定されると、対象行は登録年月が同一であるか否かに関係なく一意に取得できます。
-
登録年月は売上明細連番に完全関数従属する(主キーが決まれば一意に決まる)ため、追加の述語「登録年月 = :登録年月」は論理的にも物理的にも冗長です。
-
よって不要述語は「登録年月 = :登録年月」となります。
誤りやすいポイント
- 「索引があるから使った方が速い」と考え、無条件に複合条件を残してしまう。
- 多重処理時に登録年月で分割していると誤解し、必須と勘違いする。
- 間違って「売上明細連番 > :処理連番」が不要と答えてしまう。
FAQ
Q: 登録年月の条件を残すと性能が落ちるのですか?
A: 範囲検索は既に主索引でカバーされており、追加条件はフィルタリングに寄与しないため最適化器が無視または後段処理します。性能への影響は小さいものの冗長です。
A: 範囲検索は既に主索引でカバーされており、追加条件はフィルタリングに寄与しないため最適化器が無視または後段処理します。性能への影響は小さいものの冗長です。
Q: 多重処理で月をまたいだデータが混ざることはないのですか?
A: ホスト変数「:開始連番」「:終了連番」をジョブ1で月別に設定しており、連番範囲で管理できるため月をまたぐ問題は発生しません。
A: ホスト変数「:開始連番」「:終了連番」をジョブ1で月別に設定しており、連番範囲で管理できるため月をまたぐ問題は発生しません。
Q: 従属属性が決まるとはどういう意味ですか?
A: 主キー(売上明細連番)が決まると、その行に格納される登録年月値も唯一に決定するという関数従属を指します。
A: 主キー(売上明細連番)が決まると、その行に格納される登録年月値も唯一に決定するという関数従属を指します。
関連キーワード: 主キー、関数従属、冗長述語、範囲検索、索引選択性
設問2:〔チェックポイントリスタート機能の概要〕 について(1)〜(4)に答えよ。
問題文を見る(4)排他ロック待ちタイムアウト時間がT秒のとき、図3中の④、⑤を合わせた処理に平均A秒、⑥の処理に平均B秒、同期を取る処理に平均C秒の時間を要すると仮定する。 この場合、他のトランザクションに排他ロック待ちタイムアウトをさせないためには、少なくともN行更新するごとに同期を取らなければならない。 Nを見積もる次の計算式の(a)、(b)に入れる適切な式をT, A, B及びCを用いて答えよ。
模範解答
a:T-B-C
b:A
解説
解答の論理構成
- 問題文の前提を確認
- 「排他ロック待ちタイムアウト時間がT秒のとき、図3中の④ ⑤を合わせた処理に平均A秒、⑥の処理に平均B秒、同期を取る処理に平均C秒の時間を要すると仮定する。」
- 1バッチ(N行)処理中にロックを保持する総時間
- ④⑤:1行あたりA秒 → N × A秒
- ⑥:バッチに1回 → B秒
- 同期(COMMIT):バッチに1回 → C 秒
- よって合計はN×A + B + C秒
- タイムアウトを回避する条件
- ロック保持時間 < タイムアウト時間 T
- 不等式:N×A + B + C < T
- 変形してNを求める
- N×A < T - B - C
- よって
- (a) に入る式:T-B-C
- (b) に入る式:A
誤りやすいポイント
- ⑥と同期(COMMIT)を「行ごと」に掛かると誤解し N×B や N×C としてしまう。
- 不等式を <= として上限値を誤判定する。
- T-B-Cが負になるケースを考慮せず現実的に実行不能なNを算出する。
FAQ
Q: “同期を取る処理” と ⑥ の違いは何ですか?
A: ⑥は “CKPT” テーブル更新の SQL、同期(COMMIT)はトランザクションを確定させロックを解放する処理です。両方ともN行ごとに1回だけ実行されます。
A: ⑥は “CKPT” テーブル更新の SQL、同期(COMMIT)はトランザクションを確定させロックを解放する処理です。両方ともN行ごとに1回だけ実行されます。
Q: BやCがゼロに近い場合でも式はそのまま使えますか?
A: はい。T-B-Cがそのまま分子に入るので、BやCが小さければ許容できるNは大きくなります。
A: はい。T-B-Cがそのまま分子に入るので、BやCが小さければ許容できるNは大きくなります。
Q: T-B-Cが負になったらどうなりますか?
A: 不等式を満たすNが存在しないため、設計自体を見直しロック戦略やタイムアウト設定を変更する必要があります。
A: 不等式を満たすNが存在しないため、設計自体を見直しロック戦略やタイムアウト設定を変更する必要があります。
関連キーワード: ロック保持時間、タイムアウト、チェックポイント、COMMIT, 不等式変形




