ページの先頭行へ戻る
Symfoware Server V10.0.0 アプリケーション開発ガイド(共通編)

3.3.2 ASSIST指定でアクセスモデルを指定する

アクセスモデルは、SQL文にASSIST指定を記述することで、指定できます。

本項では、ASSIST指定の使用方法について、例を使用して説明します。

以降の例で、“在庫管理.在庫表”、“在庫管理.発注表”および“在庫管理.会社表”という表を用いています。

“在庫管理.在庫表”、“在庫管理.発注表”および“在庫管理.会社表”の表定義とデータの詳細、および格納構造は次のとおりです。

表3.1 在庫管理.在庫表(表の格納構造:SEQUENTIAL)

製品番号

製品名

在庫数量

倉庫番号

  110
  111
  123
  124
  140
  212
  215
  226
  227
  240
  243
  351

テレビ
テレビ
冷蔵庫
冷蔵庫
CDプレーヤー
テレビ
ビデオ
冷蔵庫
冷蔵庫
CDプレーヤー
CDプレーヤー
CD

    85
    90
    60
    75
  120
      0
      5
      8
    15
    25
    14
2500

  2
  2
  1
  1
  2
  2
  2
  1
  1
  2
  2
  2

表3.2 在庫管理.在庫表のインデックス

インデックスのDSO名

構成列名

INDEX1

製品番号

INDEX2

倉庫番号


表3.3 在庫管理.発注表(表の格納構造:SEQUENTIAL)

取引先

取引製品

仕入価格

発注数量

  61
  61
  61
  61
  61
  62
  62
  62
  63
  63
  63
  71
  71
  72
  72
  72
  72
  72
  74
  74
  74
  74
  74

  123
  124
  140
  215
  240
  110
  226
  351
  111
  212
  215
  140
  351
  140
  215
  226
  243
  351
  110
  111
  226
  227
  351

  48000
  64000
    8000
240000
  80000
  37500
112500
      375
  57400
205000
246000
    7800
      390
    7000
210000
105000
  84000
      350
  39000
  54000
117000
140400
      390

    60
    40
    80
    10
    20
  120
    20
  800
    80
    30
    10
    50
  600
    70
    10
    20
    10
1000
  120
  120
    20
    10
  700

表3.4 在庫管理.発注表のインデックス

インデックスのDSO名

構成列名

INDEX3

取引先

INDEX4

仕入価格

INDEX5

取引製品

表3.5 在庫管理.会社表(表の格納構造:SEQUENTIAL)

会社番号

会社名

業種コード

電話番号

地域コード

住所

61

アダム電気

111-777-4444

東京都 小田区 新蒲田 7-8-9

62

アイデア商事

222-888-5555

神奈川県 小浜市 旭区 1-2-3

63

大月産業

333-999-6666

埼玉県 浦和町 大崎 1-1-1

71

川上電気

444-111-7777

大阪府 境田市 赤坂台 4-5-6

72

龍巻産業

555-222-8888

大阪府 灘町 東淀川 2-3-7

74

第一商事

666-333-9999

京都府 中市 4-16-16

表3.6 在庫管理.会社表のインデックス

インデックスのDSO名

構成列名

INDEX6

業種コード

INDEX7

地域コード

会社表は複数のDSIに分割しており、分割キーは会社番号です。

表のDSI名

分割キー値

会社表DSI1

60~69

会社表DSI2

70~79

3.3.2.1 ASSIST指定の使用方法

ASSIST指定は、以下のSQL文のSELECTキーワードの直後の場所にコメントとして指定します。

ASSIST指定は注釈なので、ASSIST指定にエラーがあった場合でも無視して動作します。

ASSIST指定が無効となっている場合には、アドバイスとして、メッセージが以下に出力されます。メッセージに従って対処してください。

3.3.2.2 ASSIST指定の種類

ASSIST指定には、以下の種類があります。

アクセスモデルは、制約ASSIST、ジョインASSISTを使用して指定します。

3.3.2.3 制約ASSISTの使用方法

ここでは、制約ASSISTの使用方法について説明します。

制約ASSISTには、USE_INDEXがあります。

参照

USE_INDEXの一般規則については、“SQLリファレンス”の“ASSIST指定”を参照してください。

USE_INDEX

ASSIST表要素に指定された表に対して、インデックスDSO名またはインデックス名で指定したインデックスを使用した、制約系のアクセスモデルを選択します。

USE_INDEXを指定しない場合は、使用するインデックスを最適化処理が決定します。

参照

最適化処理のインデックスの選択基準は、“チューニングガイド”の“アクセス方式のチューニング”を参照してください。

注意

  • 非活性状態のインデックスのDSO名またはインデックス名は指定できません。

  • 探索条件にインデックス構成列を指定していないなど、インデックスのDSO名またはインデックス名に指定されたインデックスの検索範囲が作成できない場合でも、指定したインデックスをINDEX ALL SCANのアクセス方式で検索します。

制約ASSISTの使用例

制約ASSISTの使用例を以下に示します。

以下のようなSQL文があります。

SELECT 取引製品,仕入価格
   FROM 在庫管理.発注表
   WHERE 取引先 = :VAL1
     AND 取引製品 BETWEEN :VAL2 AND :VAL3

USE_INDEXを指定しない場合、使用するインデックスに以下の候補があり、選択率の小さいINDEX3がアクセスプランに選択されます。

  • INDEX3 を「取引先 = :VAL1」の範囲で検索

  • INDEX5 を「取引製品 BETWEEN :VAL2 AND :VAL3」の範囲で検索

取引製品に対する条件は範囲で指定できますが、:VAL2と:VAL3に同じ値が設定される場合、INDEX5を使用した方が性能が良いということになります。

そこで、インデックスDSOのINDEX5を使用して検索するように、USE_INDEXを指定します。

SELECT /* ASSIST USE_INDEX(発注表(INDEX5)) */
     取引製品,仕入価格
    FROM 在庫管理.発注表
    WHERE 取引先 = :VAL1
      AND 取引製品 BETWEEN :VAL2 AND :VAL3

3.3.2.4 ジョインASSISTの使用方法

ここでは、ジョインASSISTの使用方法について説明します。

ジョインASSISTとして、LEADING_TABLEを指定する使い方、JOIN_RULEを指定する使い方、LEADING_TABLEとJOIN_RULEを同時に指定する使い方があります。

参照

ジョインASSISTの一般規則については、“SQLリファレンス”の“ASSIST指定”を参照してください。

LEADING_TABLE

ASSIST表要素に指定された表の順にジョインします。結合表中の表も指定できます。

LEADING_TABLEを指定しない場合は、ジョイン順を最適化処理が決定します。

参照

最適化処理のジョイン順の選択基準は、“チューニングガイド”の“ジョイン方法のチューニング”および“ジョイン順のチューニング”を参照してください。

注意

  • ASSIST表要素に指定されていない表のジョイン順は、システムが自動的に決定します。

  • LEADING_TABLEが以下の規則を満たしていない場合はASSIST指定が無効になりますが、規則を満たしているASSIST表要素に関しては、先頭から順に、指定されたジョイン順に従います。

    • 結合型がLEFTの場合、結合型の左側の表よりも後ろに右側の表を指定します。

    • 結合型がRIGHTの場合、結合型の右側の表よりも後ろに左側の表を指定します。

  • 表の結合関係は、比較演算子“=”で表を結合する探索条件(例:表A.列A=表B.列B)で表現します。結合関係の探索条件は、ブール演算子“OR”でつなぎません。また、以下のいずれかの場所に指定します。

    • 結合表の結合条件

    • WHERE句

JOIN_RULE

ジョインする方法(フェッチジョインまたはマージジョイン)を指定します。

JOIN_RULEを指定しない場合は、ジョイン方法を最適化処理が決定します。

参照

最適化処理のジョイン方法の選択基準は、“チューニングガイド”の“ジョイン方法のチューニング”を参照してください。

注意

  • 以下のいずれかの表をFROM句に2個以上指定した場合は、JOIN_RULEにFETCHは指定できません。

    • ジョインキーにインデックスが定義されていない、またはクラスタキーになっていない表。

    • ジョインキーに定義したインデックスDSOまたはインデックスが非活性状態である表。

    • 結合表、導出表または制約ASSISTを指定した表。

    • CAST指定をジョインキーに指定した表。

  • 表の結合関係は、比較演算子“=”で表を結合する探索条件(例:表A.列A=表B.列B)で表現します。結合関係の探索条件は、ブール演算子“OR”でつなぎません。また、以下のいずれかの場所に指定します。

    • 結合表の結合条件

    • WHERE句

LEADING_TABLEとJOIN_RULEを同時に指定

LEADING_TABLEと、FETCHを指定したJOIN_RULEを同時に指定すると、ジョインキー以外に定義したインデックス、またはジョインキーになっていないクラスタキーを利用したフェッチジョインを行うことができます。これにより、以下の表をFROM句に2個以上指定することができます。

また、USE_INDEXも同時に指定することで、ジョインで利用するインデックスを固定することができます。

なお、インデックスまたはクラスタキーが利用できない場合は表の全件検索を行います。

ジョインASSISTの使用例

ジョインASSISTの使用例を以下に示します。

例1

以下のようなSQL文があります。

SELECT 在庫表.倉庫番号,発注表.取引製品
    FROM 在庫管理.発注表,在庫管理.在庫表
    WHERE 発注表.取引製品 = 在庫表.製品番号
      AND 発注表.取引先 > :VAL1

JOIN_RULEを指定しない場合、最適化処理はマージジョインまたはフェッチジョインのいずれかを選択します。

このSQL文では、「発注表.取引先」に対する条件の絞り込みがあります。このようにデータを少量に絞り込めるような場合、フェッチジョインの方が効率的です。

そこで、フェッチジョインを行うようにJOIN_RULEを指定します。

SELECT /* ASSIST JOIN_RULE(FETCH) */
     在庫表.倉庫番号,発注表.取引製品
    FROM 在庫管理.発注表,在庫管理.在庫表
    WHERE 発注表.取引製品 = 在庫表.製品番号
      AND 発注表.取引先 > :VAL1
例2

以下のようなSQL文があります。

SELECT 発注表.仕入価格,発注表.取引製品
    FROM 在庫管理.在庫表,在庫管理.発注表
    WHERE 在庫表.製品番号 = 発注表.取引製品
      AND 在庫表.倉庫番号 BETWEEN :VAL1 AND :VAL2
      AND 発注表.取引先 BETWEEN :VAL3 AND :VAL4

このSQL文には以下の条件が指定されているため、各表のジョイン処理に先立ってインデックス検索を行うことで、ジョインする件数を少なくすることが可能です。

  • INDEX2を「在庫表.倉庫番号 BETWEEN :VAL1 AND :VAL2」の範囲で検索

  • INDEX3を「発注表.取引先 BETWEEN :VAL3 AND :VAL4」の範囲で検索

ジョイン順として、以下の2つのうち最適な方を選択します。

  • 発注表、在庫表の順

  • 在庫表、発注表の順

フェッチジョインの起点となる表は、なるべくレコード件数が絞り込まれている表である方が性能は良くなります。

取引先に対する条件の方が業務的に絞り込める場合、INDEX3を使って絞り込んだ後、フェッチジョインするというアクセスプランが良いことになります。

そこで、インデックスDSOのINDEX3を使用して検索するように、USE_INDEXを指定し、さらに発注表、在庫表の順にジョインするようにLEADING_TABLEを指定します。ジョイン方法にはフェッチジョインを行うようにJOIN_RULEを指定します。

SELECT /* ASSIST USE_INDEX(発注表(INDEX3))
          LEADING_TABLE(発注表,在庫表)
          JOIN_RULE(FETCH) */
        発注表.仕入価格, 発注表.取引製品
    FROM 在庫管理.在庫表,在庫管理.発注表
    WHERE 在庫表.製品番号 = 発注表.取引製品
      AND 在庫表.倉庫番号 BETWEEN :VAL1 AND :VAL2
      AND 発注表.取引先 BETWEEN :VAL3 AND :VAL4
例3

以下のようなSQL文があります。

SELECT 在庫表.製品番号,COUNT(*)
    FROM 在庫管理.在庫表,在庫管理.発注表
    WHERE 在庫表.製品番号 = 発注表.取引製品
    GROUP BY 在庫表.製品番号

データ分析の用途では、さまざまな方向から分析するため、多くの場合インデックスを付けていないか、または動作環境ファイルのパラメタIGNORE_INDEXをチューニングに指定してインデックスを使用しない運用にしています。

このSQL文では、IGNORE_INDEXを指定して全件をジョインという想定です。マージジョインは、ジョインするキーのデータ値に同じ値を含まない表から順にジョインする方が性能が良くなります。

そこで、このような特徴をふまえて、在庫表、発注表の順にジョインするようにLEADING_TABLEを指定します。

SELECT /* ASSIST LEADING_TABLE(在庫表,発注表) */
       在庫表.製品番号,COUNT(*)
    FROM 在庫管理.在庫表,在庫管理.発注表
    WHERE 在庫表.製品番号 = 発注表.取引製品
    GROUP BY 在庫表.製品番号
例4

発注表、会社表の順にフェッチジョインを行いたい場合、LEADING_TABLEとJOIN_RULEを同時に指定することで可能となります。

  • INDEX5を「発注表.取引製品 = :VAL1」の範囲で検索

  • 「発注表.取引先 = 会社表.会社番号」で会社表の検索対象のDSIを限定

  • 発注表、会社表の順にフェッチジョイン

    SELECT /* ASSIST LEADING_TABLE(発注表,会社表)
              JOIN_RULE(FETCH) */
           発注表.取引製品,会社表.会社名
        FROM 在庫管理.発注表,在庫管理.会社表
        WHERE 発注表.取引先 = 会社表.会社番号
           AND 発注表.取引製品 = :VAL1
           AND 会社表.業種コード = :VAL2
           AND 会社表.地域コード = :VAL3

上記のSQL文の例では、会社表を検索する条件が複数あります。

  • INDEX6を「会社表.業種コード = :VAL2」の範囲で検索

  • INDEX7を「会社表.地域コード = :VAL3」の範囲で検索

どちらのインデックスを使用するかは最適化処理が決めます。使用するインデックスを細かく制御する場合は、USE_INDEXも同時に指定します。すると、以下のSQL文になります。

SELECT /* ASSIST LEADING_TABLE(発注表,会社表)
          JOIN_RULE(FETCH)
          USE_INDEX(会社表(INDEX6)) */
       発注表.取引製品,会社表.会社名
    FROM 在庫管理.発注表,在庫管理.会社表
    WHERE 発注表.取引先 = 会社表.会社番号
       AND 発注表.取引製品 = :VAL1
       AND 会社表.業種コード = :VAL2
       AND 会社表.地域コード = :VAL3

3.3.2.5 ASSIST指定の注意事項

ASSIST指定を利用する場合の注意事項を以下に示します。

ASSIST要素の優先順位

矛盾するASSIST要素を組み合わせた場合、優先順位の低い方のASSIST要素が無効になります。

ASSIST指定の優先順位は、以下のとおりです。なお、正しく指定された他のASSIST要素は有効となります。

  1. USE_INDEX

  2. LEADING_TABLE

  3. JOIN_RULE

  4. FIRST_ROWS


FIRST_ROWSについては、“3.5.1.1 実行制御ASSISTの使用方法”を参照してください。


矛盾するASSIST要素を組み合わせた例を以下に示します。

USE_INDEXを発注表と在庫表に指定しているので、JOIN_RULEに従ったフェッチジョインが不可能です。このような場合、優先順位に従って、JOIN_RULEが無効になります。優先順位が高いUSE_INDEXは、2つとも有効になります。

SELECT /* ASSIST USE_INDEX(発注表(INDEX3))
          USE_INDEX(在庫表(INDEX2))
          JOIN_RULE(FETCH) */
       発注表.仕入価格,発注表.取引製品
    FROM 在庫管理.在庫表,在庫管理.発注表
    WHERE 在庫表.製品番号 = 発注表.取引製品
      AND 在庫表.倉庫番号 = 2
      AND 発注表.取