クエリの冗長な分岐の除外 (分割和結合)

クエリの実行対象であるビューのいずれかの定義と、そのクエリの条件との間に互換性がない場合、ビューのその分岐が実行エンジンによってクエリプランから除外されます。この分岐からは行が返されないことがわかっているからです。

ビューのデータを複数の水平分割 (シャード) から取得していて、各分割が互いに別々のデータソースに保存されている場合に、この機能が効果的です。たとえば、今年の売上データが Oracle データベースに保存されていて、昨年以前の売上データが Hadoop クラスターに保存されている場合です。

普通、このようなシナリオでは、それぞれが各分割を表す複数のビューで構成する和結合ビューを定義します。多くの場合、このタイプの和結合ビューに実行したクエリでは、いずれか 1 つのソースのみからデータが取得されます。たとえば、きわめて多くのクエリで今年の売上データが扱われる一方で、昨年以前の売上データが扱われないことがあります。

このタイプの和結合ビューの場合、WHERE 条件によっては、クエリの実行対象ではない分岐を Virtual DataPort の実行エンジンで除外できます。これにより、和結合ビューのほか、すべての操作をデータソースに委任できます。

分割和結合を作成するには、あるデータソースに保存されているデータに、そのデータを他のデータソースに保存されているデータと区別する属性があるかどうかに応じて、以下の 2 つの方法があります。


データを区別する属性がある場合の分割和結合の作成

たとえば、以下の基本ビューがあるとします。

  • sales_oracle: 今年の売上を返すビュー。

  • sales_hadoop: 昨年以前の売上を返すビュー。

どちらのビューにも、販売日付を示す sale_date フィールドが存在します。

このシナリオでは、以下の手順に従って分割和結合を作成します。

  1. 条件 sale_date >= TRUNC(CURRENT_DATE, 'Y') を使用して sales_oracle から選択ビューを作成します。

    この関数は、今年の元旦の日付値を返します。

  2. 条件 sale_date < TRUNC(CURRENT_DATE, 'Y') を使用して sales_hadoop から別の選択ビューを作成します。

  3. 上記の 2 つの選択ビューの和結合を作成します。

WHERE 条件を指定せずにこの和結合ビューにクエリを実行すると、Oracle と Hadoop から売上が取得されます。

sale_date フィールドを使用した条件を指定してこの和結合にクエリを実行すると、そのクエリの WHERE 条件と互換性のない WHERE 条件が設定されたビューが、実行エンジンによって実行プランから除外されます。WHERE 条件を設定した選択ビューが必要になる理由はこの点にあります。

たとえば、過去 7 日間の売上を取得するには、以下のクエリを実行する必要があります。

SELECT *
FROM sales
WHERE sale_date >= ADDDAY(CURRENT_DATE, -7)

今日が今年の 8 日目以降である場合、実行エンジンによって、クエリの実行対象を sales_oracle 基本ビューのみとすれば良いことが検出され、実行プランから sales_hadoop ビューの分岐が除外されます。

分岐の 1 つを除外することの利点は、より多くの操作をソースにプッシュダウンでき、それらを Virtual DataPort で実行する必要がなくなることです。これによって、クエリのパフォーマンスが向上します。

たとえば、以下のクエリを実行した場合、 GROUP BY をソースにプッシュダウンできます。

SELECT sales_rep, SUM(total)
FROM sales
WHERE sale_date >= ADDDAY(NOW, -7)
GROUP BY sales_rep

以下の図に、この最適化前と最適化後のクエリプランを示します。

Example of pruning a branch in a partitioned union

WHERE 条件を指定していない場合、このクエリでは Oracle と Hadoop から売上データが返され、GROUP BY はプッシュダウンできません。


データを区別する属性がない場合の分割和結合の作成

ビューを区別するフィールドが存在しない場合でもそれらの和結合を実行できます。そのためには、合成フィールドを備えた選択ビューを各基本ビューから 1 つずつ作成し、そのフィールドに対する条件を指定した選択ビューを作成したうえで、それらの選択ビューの和結合を実行する必要があります。たとえば、次のように、ある地域の売上データをあるデータベースに、別の地域の売上データを別のデータベースに、それぞれ保存しているとします。

  • sales_eu: 欧州の売上を返すビュー。

  • sales_na: 北米の売上を返すビュー。

これらのどのビューにも、売上が得られた地域を区別できるフィールドは存在しません。

このシナリオでは、以下の手順に従って分割和結合を作成します。

  1. sales_eu から、 territory フィールドの値に 'EU' を指定した選択ビューを p_sales_eu の名前で作成します。以下に例を示します。

    CREATE VIEW p_sales_eu AS
    SELECT *, 'EU' as territory
    FROM sales_eu
    
  2. p_sales_eu から、 WHERE 条件として territory = 'EU' を指定した選択ビューを作成します。以下に例を示します。

    CREATE VIEW p_p_sales_eu AS
    SELECT *
    FROM p_sales_eu
    WHERE territory = 'EU'
    
  3. sales_na から、 p_sales_na を名前とする選択ビューを作成します。以下に例を示します。

    CREATE VIEW p_sales_na AS
    SELECT *, 'NA' as territory
    FROM sales_na;
    
  4. p_sales_na から、 WHERE 条件として territory = 'NA を指定した選択ビューを作成します。

    CREATE VIEW p_p_sales_na AS
    SELECT *
    FROM p_sales_na
    WHERE territory = 'NA'
    
  5. 上記の 2 つの選択ビューの和結合を作成します。

この和結合ビューにクエリを実行すると、前の例と同じ最適化が実行エンジンによって適用されます。