【令和３年度秋】R3データベーススペシャリスト試験　解説【午後Ⅰ問２設問１(１)】

復習を兼ねて、超個人的な解説をしてみます:exclamation: 
ただし、2021/10/16執筆時点で公式の解答が出ていないので、完全に私オリジナルの解釈になります。
非公式の解答速報をもとにしていますが、間違っていたらごめんなさい（気づいたときに修正します:pencil:）

# 午後Ⅰ　問２
データベースの実装に関する次の記述を読んで、設問1～3に答えよ。
※「次の記述」は省略。下部のリンクからPDF参照。
## 設問１　(1)　解答
本文中の空欄a～hに適切な語句を埋めて完成させた文章は、おそらく以下の通りだと思います。

Fさんは、利用明細抽出処理の処理時間を、次のように見積もった。

1. このSQL文での票の結合方法を調べたところ、"オーソリ履歴"テーブルを外側、"加盟店"テーブルを内側とする入れ子ループ法だった。"オーソリ履歴"テーブルのアクセス経路は表探索だったので、**a)24億** ページを非同期に読み込む。
2. ディスク転送速度を100Mバイト/秒と仮定すれば、24億ページを非同期に読み込むデータ出力処理時間は**b)96000** 秒である。
3. カード数を1000万枚、カード・月当たり平均オーソリ回数を80回、審査結果がすべて可であると仮定すると、"オーソリ履歴"テーブルの結果行数は**c)8** 億行である。
4. この結合では、外側の表の結果行ごとに"加盟店"テーブルの主キー索引を索引探索し、"加盟店"テーブルを１行、ランダムに合計**d)8億** 回読み込む。
5. 索引はバッファヒット率100%、テーブルはバッファヒット率0%とすれば、"加盟店"テーブルを合計で**e)2億** ページを同期的に読み込むことになる。同期読み込みにページ当たり1ミリ秒かかると仮定すれば、同期データ入出力処理時間は**f)20万** 秒である。
6. 内側の表の索引探索と結合にかかるCPU時間は、1結果行あたり0.01ミリ秒かかると仮定すれば、**g)8000** 秒である。
7. 外側の表のCPU時間は96000秒、内側の表のCPU時間は8000秒、内側の表の同期データ入出力処理時間は20万秒なので、SQL文の処理時間を**h)304000** 秒と見積もった。

表１　主なテーブルの将来の容量見積もり

| テーブル名 | 行長（バイト） | 見積行数 | １ページ当たりの行数 | ページ数 | 容量(GB) |
|:-:|:-:|:-:|:-:|:-:|:-:|
| 加盟店 | 1000 | 100万 | 4 | 25万 | 1 |
| オーソリ履歴 | 200 | 480億 | 20 | 24億 | 9600 |

## 解説
### a)
[RDBMSの主な仕様]の中に``表探索では、索引を使わずに先頭ページから順に全行を探索する`` とあるので、読み込むページ数は表１のオーソリ履歴×ページ数より**24億** 行となる。

### b)
オーソリ履歴の全データ容量は、表１より9600 GBとわかる。
よって、

```
9600GB ÷ 100MB/秒
＝ 9600GB ÷ 0.1GB/秒
＝ 96000秒
```
**96000** 秒が正解となる。

### c)
`カード・月当たり平均オーソリ回数 ＝ 80回`というのは、１枚のカード当たり80回/月のオーソリ処理があるということ。
:arrow_right: つまりオーソリ履歴テーブルに80レコード存在するということである。
カード枚数は1000万枚とのことなので、1000万 × 80回 ＝ **8億**行が答えとなる。

### d)
上記c)より、オーソリ履歴テーブルのレコード数が8億行となった。
主キー索引は、問題文より`where句中の述語に適した索引によって絞り込んで`検索を行う。
加盟店テーブルは主キー索引であるため、加盟店番号によって加盟店テーブルが１レコードに絞り込まれる。
また、問題文に

```
"オーソリ履歴"テーブルを外側、"加盟店"テーブルを内側とする入れ子ループ法
```
とあるので、オーソリ履歴テーブル１行に対し、絞り込み済みの加盟店テーブルを１レコードを読み込むことになる。
よって、合計読み込み回数は1回 × 8億レコード ＝ **8億**回となる。

### e)
上記d)より、加盟店テーブルを８億レコード読み込むとする。
また、表１より加盟店テーブルは、１ページ当たり４行のレコードを持っているので、8億レコード ÷ 4行 ＝ **2億**ページを読み込むことになる。

### f)
上記e)より、2億ページを読み込む。
１ページ当たりの読み込みが1ミリ秒＝0.001秒なので、データ入出力処理時間は２億ページ × 0.001秒 ＝ **20万**秒となる。

### g)
問題文より

```
外側のテーブル・・・オーソリ履歴
内側のテーブル・・・加盟店
```
なので、内側の表と索引探索と結合は、上記c)より８億レコード分必要になる。
１レコード当たりの所要時間が0.001ミリ秒なので、

```
８億レコード × 0.001ミリ秒
＝ 800万ミリ秒
＝ 8000秒
```
よって、内側の表と索引探索と結合にかかる時間は、 **8000**秒となる。

### h)
問題文より同期データ入出力処理にかかる時間は

```
SQL処理時間 ＝ CPU時間 ＋ 同期データ入出力処理時間
```
であるため、上記f)とg)より

| 処理内容| 時間 |
|:-:|:-:|
| 外側の表のCPU時間 | 96000秒 |
| 内側の表のCPU時間 | 8000秒 |
| 内側の表の同期データ入出力処理時間 | 20万秒 |
この３つの値を足した結果である**30万4000**秒が答えとなる。

# 個人的な感想

落ち着いて問題文を読めばそんなに難しい問題じゃなかった気がするし、なんなら最初の方は表１に正解が書いてあった。
・・・が、試験当日は緊張と焦りでa）をいきなり間違えてしまい、その後の計算式はそこそこ正しかったにもかかわらず、a）のせいで全滅しました:sob:
まだまだ修行が足りなかったです。

なお、繰り返しになりますが、非公式の解答速報を見ながら、試験後に改めてゆっくり解いてみた結果なので、間違ってる可能性もあります:bangbang:
公式の解答が出るまでは、この記事は参考程度にお願いします。

# 参考情報

問題文はこちら :point_down: 
[令和3年度秋期試験 データベーススペシャリスト試験 午後Ⅰ](https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2021r03_2/2021r03a_db_pm1_qs.pdf, "令和3年度秋期試験 データベーススペシャリスト試験 午後Ⅰ")

参考にした解答速報はこちら:point_down:
:large_orange_diamond:[解答速報 令和3年度秋期試験｜情報処理｜資格の学校TAC[タック]](http://www.tac-school.co.jp/kaitousokuhou/downloads/13_R3F_DB%E8%A7%A3%E7%AD%94%E4%BE%8B.pdf, "解答速報 令和3年度秋期試験｜情報処理｜資格の学校TAC[タック]")
:large_orange_diamond:[情報処理技術者試験 | 解答速報・自動採点サービス | IT技術者資格取得ならアイテック](https://www.itec.co.jp/wp-content/uploads/shiken/2021a/2021a_db_pm1_kaito_n.pdf, "情報処理技術者試験 | 解答速報・自動採点サービス | IT技術者資格取得ならアイテック")