データベースにおける VARCHAR および VARGRAPHIC データ・タイプの使用上のヒント

可変長列 (VARCHAR または VARGRAPHIC) のサポートを使用すると、 1 つのテーブルに可変長の列としていくつでも列を定義することができます。 VARCHAR または VARGRAPHIC サポートを使用すると、通常、 テーブルのサイズを小さくすることができます。

可変長列のデータは、内部では 2 つの区域に保管されます。 すなわち、固定長または ALLOCATE 域とオーバーフロー域です。 デフォルト値を指定すると、割り振られた長さは少なくとも値と同じ大きさになります。 次の点を考慮すると、記憶域の最良の使い方を決定する際に役立ちます。

可変長データをもつテーブルを定義するときは、ALLOCATE 域の幅を決定する必要があります。 その幅は、主要目的によって異なります。

  • スペースの節約: ALLOCATE(0) を使用します。
  • パフォーマンス: ALLOCATE 域の幅は、その列の値の少なくとも 90% から 95% を収容できるだけの大きさでなければなりません。

スペースの節約とパフォーマンスとのバランスをとることもできます。 次の例は電子電話帳の例で、以下のデータを使用しています。

  • 8600 人分の名前を姓、名、およびミドル・ネームで示したもの。
  • Last、First、および Middle の各列は可変長です。
  • 最も短い姓は 2 文字で構成され、最も長い姓は 22 文字で構成されます。

この例では、可変長の列を使用するとどの程度スペースを節約できるかを示しています。 固定長の列で構成したテーブルは、使用するスペースが最も大きくなります。 ALLOCATE 域のサイズを慎重に計算してテーブルを作成すると、 使用するディスク・スペースは少なくてすみます。 また、ALLOCATE 域を使用せずに (すなわち、すべてのデータをオーバーフロー域に保管して) テーブルを定義すると、使用するディスク・スペースは最小になります。

表 1. 可変長の列で使用するディスク・スペース
サポートの 種類 姓列の最大値/ 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 列に限定することが可能です。