クエリー・リライト (Query Rewrite)

クエリー・リライトとは、元のクエリーをより高速にチューニングするためにオラクルが自動的に違うクエリーに再構築する(書き換える)機能である。

有名な例として、マテリアライズド ビューを使ったクエリーリライトがある。
明細票と各種サマリ表が存在している場合に、複数の表 (VIEW) の存在を気にすることなく自動的に SELECT における FROM 先を適切なサマリー表に書き換えてくれる。

クエリー・リライトを使用するために特別なプログラムは必要ない、設定をするだけで Oracle が勝手に SQL をクエリーを書き換えてくれる。

例) 売り上げの明細票と 2つのサマリ表(商品別・月別サマリ表と 商品別サマリ表)の場合のステップ

  1. ベース表とサマリ表(マテリアライズド・ビュー)を作成する。
  2. ベース表にアクセスするSQLを、マテリアライズド・ビューを使用したSQLに自動書き換え(Query Rewrite)許可する。
  3. ベース表へのSQLを実行してもサマリ表にアクセスさせる。
-- 売り上げサンプル表(明細)
CREATE TABLE RIVUS.SALES
(
    PRODUCT_NO                     VARCHAR2(5),
    SALES                          NUMBER,
    SALE_ON                        DATE
);
 
--サンプル・マテリアライズドビュー
--- 月別・商品別 売上
DROP MATERIALIZED VIEW RIVUS.SALES_SUM_PRODUCT_MONTH;
 
CREATE MATERIALIZED VIEW
  SALES_SUM_PRODUCT_MONTH
BUILD IMMEDIATE
REFRESH COMPLETE
ENABLE QUERY REWRITE
AS
SELECT
       PRODUCT_NO, TRUNC(SALE_ON, 'MONTH') SALE_ON, SUM(SALES) SUM_SALES
  FROM
       SALES
GROUP BY
       PRODUCT_NO, TRUNC(SALE_ON, 'MONTH')
;
--- 商品別 売上
DROP MATERIALIZED VIEW RIVUS.SALES_SUM_PRODUCT;
 
CREATE MATERIALIZED VIEW
  SALES_SUM_PRODUCT
BUILD IMMEDIATE
REFRESH COMPLETE
ENABLE QUERY REWRITE
AS
SELECT
       PRODUCT_NO, SUM(SALES) SUM_SALES
  FROM
       SALES
GROUP BY
       PRODUCT_NO
;

クエリー・リライトを 使用可能にする。

ALTER SESSION SET QUERY_REWRITE_ENABLED=TRUE; { TRUE | FALSE | FORCE } 

クエリーが書き換えられるSQL例(使用しているヒント句はコストを無視して適用させる。通常は不要)

-- 月別 商品別 サマリ表への書き換え
SELECT /*+ REWRITE(SALES_SUM_PRODUCT_MONTH) */
       PRODUCT_NO, SUM(SALES) SUM_SALES
  FROM
       SALES
 WHERE
       PRODUCT_NO = 'F001'
       AND TRUNC(SALE_ON, 'MONTH') = TO_DATE('2005/10','YYYY/MM')
GROUP BY
       PRODUCT_NO, TRUNC(SALE_ON, 'MONTH');
--
-- オラクル内部では、以下のように変換されて実行される。
SELECT
       PRODUCT_NO, SUM_SALES
  FROM
       SALES_SUM_PRODUCT_MONTH
 WHERE
       PRODUCT_NO = 'F001'
       AND SALE_ON = TO_DATE('2005/10','YYYY/MM')
-- 商品別 サマリ表への書き換え
SELECT /*+ REWRITE(SALES_SUM_PRODUCT) */
       PRODUCT_NO, SUM(SALES) SUM_SALES
  FROM
       SALES
 WHERE
       PRODUCT_NO = 'F001'
GROUP BY
       PRODUCT_NO
--
-- オラクル内部では、以下のように変換されて実行される。
SELECT
       PRODUCT_NO, SUM_SALES
  FROM
       SALES_SUM_PRODUCT
 WHERE
       PRODUCT_NO = 'F001'


クエリー・リライトの関連トピックス

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ Oracle Web セミナー