クエリー・リライト (Query Rewrite)
クエリー・リライトとは、元のクエリーをより高速にチューニングするためにオラクルが自動的に違うクエリーに再構築する(書き換える)機能である。
有名な例として、マテリアライズド ビューを使ったクエリーリライトがある。
明細票と各種サマリ表が存在している場合に、複数の表 (VIEW) の存在を気にすることなく自動的に SELECT における FROM 先を適切なサマリー表に書き換えてくれる。
クエリー・リライトを使用するために特別なプログラムは必要ない、設定をするだけで Oracle が勝手に SQL をクエリーを書き換えてくれる。
例) 売り上げの明細票と 2つのサマリ表(商品別・月別サマリ表と 商品別サマリ表)の場合のステップ
- ベース表とサマリ表(マテリアライズド・ビュー)を作成する。
- ベース表にアクセスするSQLを、マテリアライズド・ビューを使用したSQLに自動書き換え(Query Rewrite)許可する。
- ベース表への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'