17.00 - 17.05 - ビューの折重ね - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLリクエストおよびトランザクション処理

Product
Advanced SQL Engine
Teradata Database
Release Number
17.00
17.05
Published
2020年6月
Content Type
プログラミング リファレンス
ユーザー ガイド
Publication ID
B035-1142-170K-JPN
Language
日本語 (日本)

ビューの折重ねは、ビューを参照する問合わせを、そのビューへの明示的な参照なしに書き換える、重要なクエリー リライト技術です。ビューを折り重ねることにより、ビューの結果についてのスプールを作成する必要がなくなり、結合プランナーで追加の結合順序を考慮できるようになります(最適化ルーチンの結合計画を参照)。

ビューと派生テーブルの意味は同じです。したがって、ビューに適用されるこの節の条件は、派生テーブルにも等しく適用され、ビューへの言及は、文の意味内容を変えないまま、派生テーブルへの言及として置き換えることができます。

ただし、ビューは常に折り重ねることができるわけではありません。例えば、別のテーブルに結合されている集約があるビューは、スプールする必要があります。

ビュー折重ねの例

次のビュー定義と問合わせについて考えてみます。

     CREATE VIEW sales_by_product AS
     SELECT product_key, product_name, SUM(quantity*amount) AS total
     FROM sales, product
     WHERE sales_product_key = product_key
     GROUP BY product_key, product_name;

     SELECT product_name
     FROM sales_by_product
     WHERE total > 50000;

包含問合わせブロックから切り離してビューの結果を評価する必要はありません。このため、ビューの折重ねは、次の書き換えられた問合わせの生成時に適用できます。

     SELECT product.product_name
     FROM sales, product
     WHERE sales_product_key=product.product_key
     GROUP BY product.product_key, product.product_name
     HAVING (SUM(quantity * amount))>50000;

一方、ビューをスプールすることは、ビュー定義が具体化され、主問合わせ内で単一のリレーションとして処理されることを意味します。

クエリー リライトは可能な場合はいつでもビューを折り重ねようと試みます。これは、ビューを折り重ねると、最適化ルーチンに問合わせを最適化するためのオプションがより多く提供されるためです。一方、ビューをスプールすると、そのテーブルを主問合わせで他のテーブルに直接結合することはできません。

ビューの折重ねの重要な例として、次の例に示されているようなUNION ALLビューの折重ねがあります。

     SELECT *
     FROM sales;

この例では、saleは、年間12の販売月のうち、11のUNION ALL演算を含むビューです。

この問合わせは次のように書き換えられます。

     SELECT *
     FROM sales1
     UNION ALL
     SELECT *
     FROM sales2
     UNION ALL
      …
     UNION ALL
     SELECT *
     FROM sales12;

次のビュー定義と問合わせについて考えてみます。

     CREATE VIEW jan_sales AS
     SELECT sales_product_key, ZEROIFNULL(quantity) AS qty
     FROM sales1;
     SELECT product_name, SUM(qty)
     FROM product LEFT OUTER JOIN jan_sales
                  ON product_key=sales_product_key
     GROUP BY product_key, product_name ;

単純に、ビューの折り重ねは、数量の値をsales1の場合のようにNULLにすることができる(その場合、ZEROIFNULL式の値は0になります)か、または製品内の行に対してsales1で一致する値がない(その場合、ZEROIFNULL式の値はNULLになります)ため不正確です。 ビューの折重ねでは、sales1の数量が最初に(外部結合の作成前に) NULLだったかどうかを追跡することによってこの問題が解決され、この追跡に基づいて正しい値が生成されます。 これは、次のように、jan_salesビューに対するクエリーに正しい書き換えを実行することができます。

     SELECT product_name, SUM(CASE
                                  WHEN sales1.ROWID IS NULL
                                  THEN NULL
                                  ELSE quantity
                              END)
     FROM product LEFT OUTER JOIN sales1
                  ON product_key=sales_product_key
     GROUP BY product_key, product_name;