データベースにおける VARCHAR および VARGRAPHIC データ・タイプの使用上のヒント
可変長列 (VARCHAR または VARGRAPHIC) のサポートを使用すると、 1 つのテーブルに可変長の列としていくつでも列を定義することができます。 VARCHAR または VARGRAPHIC サポートを使用すると、通常、 テーブルのサイズを小さくすることができます。
可変長列のデータは、内部では 2 つの区域に保管されます。 すなわち、固定長または ALLOCATE 域とオーバーフロー域です。 デフォルト値を指定すると、割り振られた長さは少なくとも値と同じ大きさになります。 次の点を考慮すると、記憶域の最良の使い方を決定する際に役立ちます。
可変長データをもつテーブルを定義するときは、ALLOCATE 域の幅を決定する必要があります。 その幅は、主要目的によって異なります。
- スペースの節約: ALLOCATE(0) を使用します。
- パフォーマンス: ALLOCATE 域の幅は、その列の値の少なくとも 90% から 95% を収容できるだけの大きさでなければなりません。
スペースの節約とパフォーマンスとのバランスをとることもできます。 次の例は電子電話帳の例で、以下のデータを使用しています。
- 8600 人分の名前を姓、名、およびミドル・ネームで示したもの。
- Last、First、および Middle の各列は可変長です。
- 最も短い姓は 2 文字で構成され、最も長い姓は 22 文字で構成されます。
この例では、可変長の列を使用するとどの程度スペースを節約できるかを示しています。 固定長の列で構成したテーブルは、使用するスペースが最も大きくなります。 ALLOCATE 域のサイズを慎重に計算してテーブルを作成すると、 使用するディスク・スペースは少なくてすみます。 また、ALLOCATE 域を使用せずに (すなわち、すべてのデータをオーバーフロー域に保管して) テーブルを定義すると、使用するディスク・スペースは最小になります。
サポートの 種類 | 姓列の最大値/ ALLOCATE 域 | 名列の最大値/ ALLOCATE 域 | ミドルネーム列の最大値/ ALLOCATE 域 | 物理ファイル全体のサイズ | オーバーフロー・スペースの行数 |
---|---|---|---|---|---|
固定長 | 22 | 22 | 22 | 567 K | 0 |
可変長 | 40/10 | 40/10 | 40/7 | 408 K | 73 |
可変長のデフォルト | 40/0 | 40/0 | 40/0 | 373 K | 8600 |
多くのアプリケーションでは、パフォーマンスを考慮しなければなりません。 デフォルトの ALLOCATE(0) を使用すると、ディスク装置のトラフィックが 2 倍になります。ALLOCATE(0) では、行の固定長部分の読み取りとオーバーフロー・スペースの読み取りをそれぞれ 1 回ずつ、 合わせて 2 回の読み取りが必要です。 ALLOCATE を慎重に指定して可変長を使用すると、 オーバーフローの発生と必要なスペースは最小になり、 パフォーマンスは最高になります。 テーブルのサイズは、固定長を使用した場合より 28% 小さくなっています。 1% 分の行はオーバーフロー域に入っているので、2 回の読み取りを要するアクセスは最低限になります。 可変長を使用すると、固定長を使用した場合と同程度のパフォーマンスを発揮します。
ALLOCATE キーワードを使用してテーブルを作成する場合は、次のようにコーディングします。
CREATE TABLE PHONEDIR
(LAST VARCHAR(40) ALLOCATE(10),
FIRST VARCHAR(40) ALLOCATE(10),
MIDDLE VARCHAR(40) ALLOCATE(7))
ホスト変数を使用して可変長の列の挿入または更新を行う場合は、可変長のホスト変数を使用してください。 ブランクは固定長ホスト変数から切り捨てられないので、固定長ホスト変数を使用した場合、あふれてオーバーフロー・スペースに入れられることになる行数が多くなる可能性があります。 この場合、テーブルのサイズも大きくなります。
次の例では、固定長ホスト変数を使用してテーブルに 1 行挿入します。
01 LAST-NAME PIC X(40).
…
MOVE "SMITH" TO LAST-NAME.
EXEC SQL
INSERT INTO PHONEDIR
VALUES(:LAST-NAME, :FIRST-NAME, :MIDDLE-NAME, :PHONE)
END-EXEC.
この場合、ホスト変数 LAST-NAME は、可変長ではありません。 文字ストリング“SMITH”の後に 35 個のブランクが付いたものが、 VARCHAR 列 LAST に挿入されます。 この値は、10 という割り振りサイズより大きくなっています。 後続の 35 個のブランクのうち、30 個はオーバーフロー域に入ります。
次の例では、可変長ホスト変数を使用してテーブルに 1 行挿入します。
01 VLAST-NAME.
49 LAST-NAME-LEN PIC S9(4) BINARY.
49 LAST-NAME-DATA PIC X(40).
…
MOVE "SMITH" TO LAST-NAME-DATA.
MOVE 5 TO LAST-NAME-LEN.
EXEC SQL
INSERT INTO PHONEDIR
VALUES(:VLAST-NAME, :VFIRST-NAME, :VMIDDLE-NAME, :PHONE)
END-EXEC.
この場合のホスト変数 VLAST-NAME は可変長です。 データの実際の長さは 5 にセットされます。 この値は、割り振られた長さより小さくなっています。 したがって、この値は列の固定長部分に入れることができます。
可変長の列を含むテーブルに対して 物理ファイル・メンバーの再編成 (RGZPFM) コマンドを実行すると、 パフォーマンスを向上させることができます。 オーバーフロー域の使用されていない部分の断片は、物理ファイル・メンバーの再編成 (RGZPFM) コマンドによって圧縮させることができます。 この技法は、オーバーフローした行の読み取り時間は短縮され、参照対象の位置の限定がさらに図られ、逐次バッチ処理のために最適の順序が得られます。
可変長列については、適切な最大長を指定してください。 指定した長さが長すぎると、処理アクセス・グループ (PAG) が増大します。 PAG が大きくなると、パフォーマンスが低下します。 また、最大長が大きいと、SEQONLY(*YES) を指定しても効率が悪くなります。 可変長の列が 2000 バイトを超えると、その列はキー列としては使用できません。
同一テーブルでの LOB および VARCHAR の使用
VARCHAR 列と同一の方式で割り振られた LOB 列を保管します。オーバーフロー記憶域に格納された列を参照している場合、現行の領域にある列すべてがメモリーにページインされます。オーバーフロー域のより小さな VARCHAR 列は、必要以上に LOB 列のページングを強制する可能性があります。 例えば、アプリケーションで取得された VARCHAR(256) 列には、同じ行にある 2 つの 5MB BLOB 列がページインされるという副次作用があります。 この副次作用を回避するため、ALLOCATE キーワードを使用して、オーバーフロー域に格納する列を LOB 列に限定することが可能です。