結合操作の最適化

Virtual DataPort のクエリ最適化で重要な要素は、最適な結合操作方法の選択です。Virtual DataPort では、内部のコストデータに基づいて結合方法が選択されます。ただし、ユーザー側で最適と考えられる特定の結合方法を明示的に適用することもできます。

結合の実行方針を決定する要素として、結合操作を実装する 方法 と結合の入力ビューを考慮する 順序 の 2 つがあります。Virtual DataPort では、以下の実行方法がサポートされています。

  • マージ結合: 「 Merge Join 」を参照してください。

  • ネスト結合: 「 Nested Join 」を参照してください。

  • ネスト並列結合: 「 Nested Parallel Join 」を参照してください。

  • ハッシュ結合: 「 Hash Join 」を参照してください。

この実行方針が適用できないシナリオで、クエリまたはビューからその方針を使用するとエラーメッセージが返されます。

マージ結合

マージ結合の方法では、結合条件のフィールドで並べ替えた 2 つのビューを、ほとんどの場合、最も少ないメモリ消費量で最も速く結合できます。

実行エンジンでマージ結合を実行する場合は、実行エンジンによって各入力ビューから行が読み取られ、結合条件が評価されます。結合条件が成立すると、この結合から該当の行が返されます。条件が成立しない場合、結合条件のフィールドの値が小さいほうの行が破棄されます。どちらのビューも並べ替えられているので、破棄した行は他方のビューの以降のどの行とも一致しないからです。

どちらかのテーブルの行がすべて処理されるまで、実行エンジンによってこのプロセスが繰り返されます。その時点で他方のビューに未処理の行が残っていても、それらは他のどの行とも一致しないので、それ以上処理する必要はありません。

マージ結合は、結合の入力ビューが結合属性で並べ替えられている場合にのみ使用できます。以下の各状況で、並べ替えられたデータが実行エンジンで取得されるので、マージ結合を実行できます。

  • 結合の基盤となるビューで、結合条件のフィールドでデータを並べ替える ORDER BY を使用している場合。

  • データを取得する場所が、テーブルまたはビューから作成された JDBC 基本ビューまたは ODBC 基本ビューであり、以下の条件が すべて 成立する場合。

    1. ビューのソース構成プロパティ Supports binary ORDER BY collation が yes である。

      重要

      このプロパティの値がデフォルトで yes ではない場合、その値を yes に設定しないでください。このプロパティの値がデフォルトで noである場合、そのソースにはバイナリ照合を使用してデータを並べ替える機能がありません。その場合は、データベースに送信したクエリで ORDER BY を使用していても、想定した順序でデータが並べ替えられません。その結果、誤った結果が返されることが考えられます。

      このプロパティの意味の詳細については、「 ソース構成の ORDER BY 関連プロパティ 」を参照してください。

    2. すべてのビューで同じ i18n を使用している。

    これらの条件がすべて成立すれば、実行エンジンによって、データベースに送信するクエリに ORDER BY 句が追加されます。

  • データを取得する場所が、クエリから作成された JDBC 基本ビューまたは ODBC 基本ビューであり、その基本ビューの「ラッパーソース構成」で Delegate SQL sentence as subquery オプションを何らかの理由で false に設定する必要があると、実行エンジンではマージを選択できません。ただし、結合条件の属性でデータを並べ替える ORDER BY 句を、基本ビューの SQL クエリで使用している場合は、実行エンジンでマージを選択できます。その場合、ORDER BY 句の属性をビューの Fields by which the data is sorted in the source プロパティに追加します。これによって、実行エンジンでマージを選択できるようになります。

  • データを取得する場所が非リレーショナルデータソースであり、そのデータソースから、結合条件で使用しているフィールドで並べ替えられたデータが返される場合。この場合、基本ビューの Fields by which the data is sorted in the source プロパティの値を設定します。このプロパティは、そこに設定したフィールドで基本ビューのデータを並べ替えることを指定します。

ビューの Fields by which the data is sorted in the source プロパティを設定する手順については、「 ビュー構成プロパティ 」を参照してください。

実行エンジンでは、マージ結合を選択できない場合、コストベースの最適化が有効 (「 コストベースの最適化 」を参照) で、ネスト結合のほうが効率的であると考えられる場合を除き、ハッシュ結合が使用されます。

マージ結合を実行している実行エンジンでは、一方の分岐のタプルが他方の分岐に残っているどの行とも一致しないことがわかった時点で、その分岐からのタプル取得を停止します。

ネスト結合

ネスト結合の方法では、まず結合の左辺の入力ビューにクエリを実行し、結合条件を確認するタプルを取得します。次に、結合に使用されているフィールドの値の組み合わせごとに、右辺のビューにクエリを実行します。

結合の右辺のビューでデータベース (JDBC データソースまたは ODBC データソース) からデータが取得されている場合、Virtual DataPort では、先頭のビューから取得した行ごとにクエリが実行されるのではなく、「ブロック単位」で右辺のビューからデータが取得されます。

「ブロック単位」でデータを取得するために、データソースのソース構成の Nested join optimization syntax プロパティで選択されている構文を使用してクエリが実行されます。このプロパティに指定できる値は以下のとおりです。

  • Use OR clause

  • Use IN clause

  • Use WITH clause

  • Use subquery

このプロパティに指定できる値は、データベースによって異なります。たとえば、Oracle に接続しているデータソースの場合、Use Or clause または Use IN clause のみを選択できます。

このプロパティは、[Edit Data Source] ダイアログの [Source Configuration] タブで変更します。

internet_inc_join_phone_inc ビューを以下のように定義したとします。

CREATE VIEW internet_inc_join_phone_inc
AS
SELECT ...
FROM internet_inc
NESTED ORDERED INNER JOIN
phone_inc
ON internet_inc.iinc_id = phone_inc.pinc_id

internet_inc ビューの iinc_id フィールドの値は 123 、および 4 であるとします。


Nested join optimization syntax プロパティの値が Use OR clause である場合は、データベースで以下のクエリが実行され、 phone_inc ビューのデータが取得されます。

SELECT ...
FROM phone_inc t0
WHERE ((t0.pinc_id = 1) OR (t0.pinc_id = 2) OR (t0.pinc_id = 3) OR
(t0.pinc_id = 4))

このプロパティの値が Use IN clause である場合は、以下のクエリが実行され、 phone_inc ビューのデータが取得されます。

SELECT *
FROM phone_inc t0
WHERE t0.pinc_id IN (1, 2, 3, 4)

このプロパティの値が Use WITH clause である場合は、以下のクエリが実行され、 phone_inc ビューのデータが取得されます。

WITH a0 AS ( SELECT a0.c0 FROM TABLE (VALUES 1, 2, 3, 4) AS a0 (c0) )
SELECT *
FROM phone_inc t0 INNER JOIN a0 ON (t0.PINC_ID = a0.c0)

このプロパティの値が Use subquery である場合は、以下のクエリが実行され、 phone_inc ビューのデータが取得されます。

SELECT *
FROM phone_inc t0
INNER JOIN TABLE (
    SELECT a0.c0
    FROM TABLE ( VALUES ( 1, 2, 3, 4 ) ) AS a0(c0)
    ) a0 ON (t0.PINC_ID = a0.c0)

結合の左辺のビュー (この例では internet_inc) から取得した値の量が一定値を超えると、いくつかのクエリが実行されて右辺のビュー (この例では phone_inc) からデータが取得されます。


SQL ステートメントを使用して右辺の入力ビューを作成する場合 (「 SQL クエリからの基本ビューの作成 」を参照)、その SQL ステートメントでは、Virtual DataPort でこの最適化オプションを使用できるように、補間変数 WHEREEXPRESSION を使用する必要があります (「 WHEREEXPRESSION 変数の使用 」を参照)。

ネスト並列結合

ネスト並列結合はネスト結合に似ています。相違点は、ネスト並列結合の場合、結合の右辺のビューに対する複数のサブクエリが 1 つずつ順番に発行されるのではなく、並列で同時に発行されることにあります。この結合では、並列に発行するサブクエリの最大数を指定するパラメーターが受け入れられます。

右辺のビューのデータがデータベースから取得される場合、ネスト並列結合の効率はネスト結合よりも低くなることが普通です。ネスト結合では、必要なデータをすべて取得する単一のサブクエリを生成することによってプロセスが最適化されるからです。

ハッシュ結合

入力ビューのデータが大量で、並べ替えられていない状況では、ほとんどの場合、ハッシュ結合が最も効率的な結合です。Web ソースなどのデータソースに対するクエリの遅延時間が長い場合も、ハッシュ結合が最も効果的です。このタイプの結合では、ソースに実行されるサブクエリの数が最も少なくなるからです。