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

3.5.1 ASSIST指定でSQL文の最初の1件の検索を高速化する

ASSIST指定の実行制御ASSISTを使用することで、SQL文の最初の1件の検索を高速化することができます。

3.5.1.1 実行制御ASSISTの使用方法

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

実行制御ASSISTには、FIRST_ROWSがあります。

参照

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

FIRST_ROWS

最初の1件の検索について最短の応答時間を目標にアクセスプランを選択します。

FIRST_ROWSを指定しない場合、探索条件を満たすすべての行を検索する場合の最短の応答時間を目標にしたアクセスプランを最適化処理が決定します。

FIRST_ROWSが有効になる条件

SQL文の形式が“FIRST_ROWSが有効となるSQL文の条件”をすべて満たし、排他の属性が“FIRST_ROWSが有効となる排他の属性の条件”のいずれかに該当する場合、FIRST_ROWSが有効になります。

FIRST_ROWSが有効となるSQL文の条件
  1. 問合せ指定である。

  2. DISTINCTを指定していない。

  3. 集合関数を指定していない。

  4. FROM句に実表を指定している。(注1)

  5. 副問合せを指定していない。

  6. GROUP BY句を指定していない。

  7. HAVING句を指定していない。

  8. ORDER BY句を指定した場合、ソート指定がすべて昇順または降順である。

  9. ORDER BY句のソート指定に1つの表の列のみを指定し、各ソート指定がすべてASCまたはDESCである。

  10. ORDER BY句のソート指定の列をインデックスキーの順にすべて含むインデックスが定義されている。

  11. ORDER BY句のソート指定に指定した列を持つ表について、下記のいずれかを満たす。(注2)
    ・ DSI分割していない。
    ・ DSI定義で分割値の指定を1つだけ指定しており、ORDER BY句のソート指定の列の順と分割キーの列名リストの順が一致している。
    ・ DSI定義で分割キーの列名リストで指定したすべての列に対して、WHERE句の探索条件に比較述語“=”の条件を指定している。

注1) FROM句に表を複数指定した場合はフェッチジョインが可能です。フェッチジョインについては、“3.3.2.4 ジョインASSISTの使用方法”を参照してください。

注2) データベース簡単運用の場合は、考慮する必要がありません。

FIRST_ROWSが有効となる排他の属性の条件
  1. 独立性水準がSERIALIZABLEで、占有の単位がページ、またはDSIである。

  2. 独立性水準がREAD COMMITTED、占有の単位が行で、コミットデータ即時読込み機能を利用している、またはデータベース簡単運用の場合(注3)。

  3. 独立性水準がREAD UNCOMMITTEDである。

  4. 占有モードがEXCLUSIVE LOCKで、占有の単位がページ、またはDSIである。

  5. 占有モードがSHARE LOCKで、占有の単位がページ、またはDSIである。

  6. 占有モードがFREE LOCK、占有の単位が行で、コミットデータ即時読込み機能を利用している、またはデータベース簡単運用の場合(注3)。

  7. 占有モードがNO LOCKである。

注3) コミットデータ即時読込み機能が動作するSQL文は、以下のいずれかでなければなりません。

  • 単一行SELECT文

  • 更新可能性句に、FOR READ ONLYを指定したカーソル、または更新可能性句を省略したカーソルのOPEN文

参照

コミットデータ即時読込み機能については、“1.1.12 PRECEDENCE(1)を指定したSEQUENTIAL構造の特徴と注意事項”を参照してください。

また、データベース簡単運用での排他制御については、“I.7 排他制御”を参照してください。

注意

  • リザルトバッファを使用すると、1回目のFETCH文のレスポンス時間には、リザルトバッファを満杯にする時間も含まれます。このため、少量検索においては、リザルトバッファのサイズを大きくしないでください。

実行制御ASSISTの使用例

例1

FROM句に表を1個指定した場合のFIRST_ROWSの例を以下に示します。

最初の1件の検索について最短の応答時間を目標にアクセスプランを選択します。

SELECT /* ASSIST FIRST_ROWS */
       倉庫番号,製品番号
    FROM 在庫管理.在庫表
    WHERE 製品番号 BETWEEN 123 AND 200
    ORDER BY 倉庫番号
例2

FROM句に表を複数個指定した場合のFIRST_ROWSの例を以下に示します。

ORDER BY句のソート指定の列と一致するインデックスINDEX1を使用して検索しながら、在庫表、発注表の順でフェッチジョインを行います。

SELECT /* ASSIST FIRST_ROWS */
       在庫表.製品番号,発注表.取引先
    FROM 在庫管理.在庫表,在庫管理.発注表
    WHERE 在庫表.製品番号 = 発注表.取引製品
      AND 在庫表.倉庫番号 = 2
      AND 在庫表.製品番号 > 227
    ORDER BY在庫表.製品番号 DESC

ORDER BY句のソート指定の列と一致するインデックスが複数個ある場合、どちらのインデックスを使用するかは最適化処理が決定します。更新トランザクションとのインデックスキー更新の排他の関係などで、使用するインデックスを細かく制御する場合は、USE_INDEXも同時に指定します。また、FIRST_ROWSを指定するとフェッチジョインを行いますが、ジョイン順は最適化処理が決定します。ジョイン順を細かく制御する場合は、LEADING_TABLEも同時に指定します。このような場合、以下のSQL文になります。

SELECT /* ASSIST FIRST_ROWS
          USE_INDEX(在庫表(INDEX1))
          LEADING_TABLE(在庫表,発注表) */
       在庫表.製品番号,発注表.取引先
    FROM 在庫管理.在庫表,在庫管理.発注表
    WHERE 在庫表.製品番号 = 発注表.取引製品
      AND 在庫表.倉庫番号 = 2
      AND 在庫表.製品番号 > 227
    ORDER BY在庫表.製品番号 DESC
例3

ROWNUMで指定した件数分だけを在庫表から読み込むアクセスプランを選択します。

ORDER BY句のソート指定の列と一致するインデックスINDEX2を使用して検索しながら、「ROWNUM < 11」を判定し、10件読み込むと検索を中止します。

SELECT /* ASSIST FIRST_ROWS */
       倉庫番号,製品番号
    FROM 在庫管理.在庫表
    WHERE 製品番号 BETWEEN 123 AND 200
      AND ROWNUM < 11
    ORDER BY 倉庫番号
例4

導出表にFIRST_ROWSを指定し、ROWNUMで指定した件数分だけを在庫表から読み込むアクセスプランを選択します。

ORDER BY句のソート指定の列と一致するインデックスINDEX1をINDEX ALL SCANのアクセス方式で降順に検索しながら、「ROWNUM < 6」を判定し、在庫表から5件だけを読み込みます。

SELECT 製品番号,在庫数量
    FROM (SELECT /* ASSIST FIRST_ROWS */
               製品番号,在庫数量
              FROM 在庫管理.在庫表
              WHERE 在庫数量 < 50
              ORDER BY 製品番号 DESC) AS D1(製品番号,在庫数量)
    WHERE ROWNUM < 6
例5

入れ子の導出表の最も内側にFIRST_ROWSを指定し、ROWNUMで指定した件数分だけを在庫表から読み込むアクセスプランを選択します。

ORDER BY句のソート指定の列と一致するインデックスINDEX1をINDEX ALL SCANのアクセス方式で降順に検索しながら、「ROWNUM < 11」を判定し、在庫表から10件だけを読み込みます。その後、「RN > 5」を判定し、6件目から10件目をアプリケーションに返します。

SELECT 製品番号,在庫数量
    FROM (SELECT ROWNUM,製品番号,在庫数量
              FROM SELECT /* ASSIST FIRST_ROWS */
                        製品番号,在庫数量
                     FROM 在庫管理.在庫表
                    WHERE 在庫数量 < 50
                    ORDER BY 製品番号 DESC) AS D1(製品番号,在庫数量)
             WHERE ROWNUM < 11) AS D2(RN,製品番号,在庫数量)
    WHERE RN > 5

ORDER BY句のソート指定の列と一致するインデックスが複数個ある場合、どちらのインデックスを使用するかは最適化処理が決定します。使用するインデックスを細かく制御する場合は、USE_INDEXも同時に指定します。

SELECT 製品番号,在庫数量
    FROM (SELECT ROWNUM,製品番号,在庫数量
              FROM SELECT /* ASSIST FIRST_ROWS
                             USE_INDEX(在庫表(INDEX1)) */
                        製品番号,在庫数量
                     FROM 在庫管理.在庫表
                    WHERE 在庫数量 < 50
                    ORDER BY 製品番号 DESC) AS D1(製品番号,在庫数量)
             WHERE ROWNUM < 11) AS D2(RN,製品番号,在庫数量)
    WHERE RN > 5