DB2のパフォーマンス評価方法（EXPORT/LOAD）

ＤＢ２の更改プロジェクトでＤＢ２のデータを１０００テーブル近く移行したときに、EXPORT/LOAD時間の評価方法で苦労したので、その評価方法を記載してみます。

なお、メーカーで保障している式というわけではないので、そこはご容赦を。。。


#前提
　DB2でのEXPORT/LOAD処理を前提としています(他のDBでも使える概念はあるかもしれませんが、そこは見れていません)
　あと、それなりに式とかが複雑ですので、扱うテーブル数が多い、どうにかして実計測せずにそれなりの精度で机上評価をしたいという目的むけです。対象が数テーブルであれば各テーブルごとに実計測をお勧めします。

#EXPORT

###EXPORT（基本形）
　EXPORT処理は、大きくはＤＢ内のデータをＣＳＶ・ＩＸＦ等のファイルに出力する処理のため、データ量にのみ依存した計算式を想定していましたが、実際にはデータ量が同じ場合、項目数が多いテーブルは項目数が小さいテーブルに対して性能が出ません。これは、ＤＢ内のデータをファイル出力するときに、ＤＢ２内で項目単位の処理があるためのようです。また、この項目単位の処理はＤＩＳＫ性能ではなく、ＣＰＵ性能に依存した処理となっているようです。

```
●EXPORT処理時間　基本形
　処理時間　＝　（データ量　×　ＤＩＳＫ性能指数）　＋　　（項目数　×　ＣＰＵ性能指数）
```

- データ量：admintabinfoコマンドなどで調査したＤＢ内部のデータ量を想定しています（admintabinfoの結果は通常KB単位）。ただし、admintabinfoでのデータ量は、再編成（reorg）運用をおこなっていない場合などはhigh water markとして、実データ量よりも多めになることがあります。
- ＤＩＳＫ性能指数：項目数が１項目などのテーブルで計測をおこなうことで求めます。ＤＢでの計測も難しい場合は、単純にファイルコピーなどでの計測結果、カタログ性能などを元に、下駄を履かせる形になります。

- 項目数：１テーブルあたりの項目数×レコード数です。ただし、日付項目（Dateなど）や浮動小数点項目は文字や整数項目よりもＣＰＵ性能を食うようで、私がおこなったプロジェクトでは、日付・数値項目は5倍（1項目を5項目扱いとする）することで、実計測結果とあうようになりました。
- ＣＰＵ性能指数：データ量は一定で、項目数１０、２０、３０などと増やしたテーブルで計測をおこない、最小二乗法などで傾きから求めました。計測が難しい場合は、ＭＩＰＳ値から下駄を履かせるしかありませんが、比較元がないと厳しいかもしれません。。。（試験環境で計測して、本番環境のＣＰＵ性能比で求めるなど）

EXPORTは基本的にはＤＩＳＫ　ＩＯ中心と思いきや、実はＣＰＵ処理も結構あり、私が経験したEXPORT性能試験結果では、処理時間の内訳はＣＰＵとＤＩＳＫで半々となっていました（外部ＤＩＳＫを使用しておりＤＩＳＫ　ＩＯ性能が結構高かったので、そこが影響していたようです）。テーブル構造や基盤構成にも大きく依存しますので、あくまで一例としてですが、、




###EXPORT（ＬＯＢデータ有り）
　TABLE内にBLOB/CLOBなどのＬＯＢ項目が有る場合はもう少し複雑になります。というのも、ＤＢではテーブルデータとＬＯＢデータでは、データ処理が異なるためです。また、ＬＯＢデータはファイルサイズが小さい場合は、サイズへの依存も大きいです。

```
●EXPORT処理時間　ＬＯＢデータ有り
　処理時間　＝　（データ量　×　ＤＩＳＫ性能指数）　＋　（項目数　×　ＣＰＵ性能指数）　＋　ＬＯＢ項目数　×　ＤＩＳＫ性能（ＬＯＢ xＫＢ）
```

- ＬＯＢ項目数：１テーブルあたりのＬＯＢ項目数×レコード数です。
- ＤＩＳＫ性能（ＬＯＢ xＫＢ）：こちらのスループット指数はＬＯＢサイズ（4KB, 8KB ,16KB ,,,4MB,,）への依存があるため、テーブルによって平均データ長が異なる場合は、それぞれのサイズでのパフォーマンスを求めます。

ＬＯＢありのテーブルは上記のとおり、式としては増加要素のみしかないため、基本的にはＬＯＢ無しに比べてパフォーマンスが悪くなります。ただし、ＬＯＢデータのファイルサイズが大きい場合、基本的にはＤＩＳＫＩＯ処理の割合が増えていくため、ＣＰＵ処理の割合が減っていき、ファイルサイズあたりでみると、ＬＯＢありのテーブルのほうがスループットとしては上がっていくことになります。


###EXPORT（並列実行）
　データ移行処理時間を短くするために、EXPORT処理を同時並列でおこなう場合の式です。サーバの資源が十分で理想的な場合で、シングル実行時のルートＮ倍の性能となるようです。

```
●EXPORT処理時間　並列実行
　処理時間（並列実行）　＝　処理時間（シングル）　×　　ルート（平行度Ｎ）　÷　平行度Ｎ
　　　　　　　　　　＝　処理時間（シングル）　÷　　ルート（平行度Ｎ）
```

結果として、２並列であれば１．４倍、４並列で２倍、８並列で、２．８倍の性能ということになります。

ただし、並列度をあげていくとどこかで資源的なボトルネックにあたって、むしろ遅くなっていくので、並列度をあげる場合は実環境での計測は必須と思ったほうがよいです。



#LOAD

###LOAD（基本形）
　基本的にはEXPORTと同じような考え方ですが、LOADでは索引データのリビルド処理について、計算式が追加されます。


```
●LOAD処理時間　基本形
　処理時間　＝　（データ量　×　ＤＩＳＫ性能指数）　＋　　（項目数　×　ＣＰＵ性能指数） ＋　（索引数　×　ＤＩＳＫ性能指数（索引 xＫＢ））
```

- 索引数：主キーと副次索引をあわせた数です。
- ＤＩＳＫ性能指数（索引 xＫＢ）：索引数が０個、１個、５個、１０個などのテーブルで計測をおこなうことで求めました。索引の１レコードあたりの平均サイズにも依存しており、そちらも複数パターンがある場合はバリエーションを求めています。


###LOAD（ＬＯＢデータ有り）
　こちらも考え方はEXPORTと同じです。

```
●LOAD処理時間　ＬＯＢデータ有り
　処理時間　＝　（データ量　×　ＤＩＳＫ性能指数）　＋　（項目数　×　ＣＰＵ性能指数）　＋　ＬＯＢ項目数　×　ＤＩＳＫ性能（ＬＯＢ xＫＢ） ＋　（索引数　×　ＤＩＳＫ性能指数（索引 xＫＢ））
```


###LOAD（並列実行）
　こちらも考え方はEXPORTと同じです。なお、LOAD処理を同一表スペースで並列で実施した場合、LOAD後の読み込み時のパフォーマンス悪化の可能性があります。並列実行をおこなう場合は、表スペースが異なるものに対して実施したほうがよいと思います、

```
●LOAD処理時間　並列実行
　処理時間（並列実行）　＝　処理時間（シングル）　×　　ルート（平行度Ｎ）　÷　平行度Ｎ
　　　　　　　　　　＝　処理時間（シングル）　÷　　ルート（平行度Ｎ）
```

# そのほか

そのほかの気づきや特記事項などを記載しておきます。

## EXPORT

- ファイル出力形式をCSV or IXFで変えてみましたが、私の場合は性能差は出ませんでした。（若干ＩＸＦのほうが悪いという直感とは逆の結果も、誤差の範囲）
- LOBデータ出力はLOBファイル単位と1ファイルでの出力の２方式がありますが、後者が圧倒的に早いです。上記式も1ファイルでの出力を前提に記載しています。
- EXPORT時にWHERE条件が無い場合を想定して記載していますが、条件をつける場合は性能影響が大きいので注意が必要です。アクセスパスにも依存しますが、ランダムアクセスになる場合などは大きく性能が落ちます（無条件の１割や、悪い場合には数パーセントなどまでスループットが落ちます）
- 無条件であれば大丈夫ですが、WHERE条件ありの場合はアクセスパスで先読み（プリフェッチ）をしているかどうかでパフォーマンスが変わるほか、昔のDB2だと、LOBデータは無条件でもプリフェッチ対象外だったりします
- 無条件であれば大丈夫ですが、条件をつけるとDB内の物理順と異なったデータ順でファイルが出力される可能性があります。この結果として、このEXPORT結果をLOADした場合のＤＢの物理順は元データと変わってしまいます。この結果として、特にシーケンシャルリードのパフォーマンスが移行元ＤＢよりも悪化する可能性があります。（元ＤＢのデータが汚れていた場合は、逆によくなる可能性もありますが、、）

## LOAD
- データ移行での性能評価だったため、NONRECOVERABLEオプションを使用する前提としています（障害時でもＤＢは0件スタートでよいことと、移行元ファイルがあるため）。こちらをはずす場合はロギング処理に依存した計算式を追加する必要があります、、、
- 性能系のパラメータにCPU_PARALLELISMというものがあります。デフォルトだと結構伸びやかに使いに行くので、かえって遅くなるケースもあるようです。最新のＣＰＵで使用できるスレッド数などが多い場合は抑えに行ったほうがよい場合もあるようです。（特に並列実行をおこなう場合）