マテリアライズドビュー検証 まて マテ マテビュー その6
<マテリアライズドビュー検証 まて マテ マテビュー その6>
ペンネーム:クリープ
今回からクエリーリライトの機能を検証していきます。
クエリーリライトは、SQLを切り替えてくれる便利な機能であり、高速リフレッ
シュと並んで、マテビューの特徴的な機能です。この2本柱を理解すれば、マ
テビューを使ってみよう、と思うのでは!?
■■■■■今回のあらすじ■■■■■
1)DBMS_MVIEW.EXPLAIN_REWRITE
2)クエリーリライトの条件
■環境
Microsoft Windows XP Pro
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Production
1)DBMS_MVIEW.EXPLAIN_REWRITE
クエリーリライトとは、ユーザーやアプリケーションが発行するSQL文を自動
的に書き換える機能ですが、自動的なので何をどう書きかえたのかよくわかり
ません。
実行したSQL文がどうリライトされるのか、また、何故リライトされなかったか
などを、DBMS_MVIEW.EXPLAIN_REWRITEというパッケージを利用して確認するこ
とができます。
では、実際に実行してみましょう。まずは、環境作成から。
SQL> @?/rdbms/admin/utlxrw.sql SQL> create materialized view mv_rewrite enable query rewrite as select job, sum(sal) sum_sal from emp group by job;
utlxrw.sqlでDBMS_MVIEW.EXPLAIN_REWRITEを実行した結果を格納するテーブル
(REWRITE_TABLE)が作成されます。
また、作成するマテビューには、enable query rewrite句を指定する必要があ
ります。
環境が作成されたところで、パッケージを実行してrewrite_tableを見てみま
しょう。MESSAGEという項目でリライトに関する説明を確認できます。
SQL> EXEC DBMS_MVIEW.EXPLAIN_REWRITE('select job, sum(sal) sum_sal from emp group by job'); SQL> select message from rewrite_table order by sequence; MESSAGE ----------------------------------------------------------------------- QSM-01151: 問合せはリライトされました QSM-01209: テキスト一致アルゴリズムを使用して、マテリアライズド・ビュー MV_REWRITEで問合せがリライトされました
一瞬エラーメッセージのように見えますが、マテビューMV_REWRITEにリライト
されていることが確認できます。
ちなみに、リライトされなかった場合は以下のようになります。
SQL> EXEC DBMS_MVIEW.EXPLAIN_REWRITE('select deptno, sum(sal) sum_sal from emp group by deptno', statement_id => 'REWRITE_TEST'); SQL> select message from rewrite_table where statement_id='REWRITE_TEST' order by sequence; MESSAGE ---------------------------------------------------------------------- QSM-01150: 問合せをリライトしませんでした QSM-01082: マテリアライズド・ビューMV_REWRITEと表EMPの結合は不可能です。 QSM-01102: マテリアライズド・ビューMV_REWRITEには表EMP(列DEPTNO)への後 戻り結合が必要です
パッケージ実行時にstatement_idを指定して、その実行結果のみを抽出してい
ます。
メッセージをみると、後戻り結合、というよくわからない言葉がありますが、
要はMV_REWRITEを使ってリライトをしようとしてダメだった、ということのよ
うです。
このように、DBMS_MVIEW.EXPLAIN_REWRITEを使用することで、実行したSQL文
がどのようにリライトされたのか、また、なぜリライトに失敗したのたのかを
確認することができます。
では、このパッケージを利用して、クエリーリライトがどのようにクエリーを
リライトしているか、について見てみましょう。
2)クエリーリライト
クエリーリライトとは読んで字のごとくクエリーをリライトする機能です。
先ほどの例のように、実行したSQL文とマテビューが同じであれば、当然リラ
イトされます。(SQL文とマテビューのコストを比較してマテビューのコスト
が低ければですが。)
では、クエリーリライトは実行したSQL文とマテビューが全く同じ場合だけに
実行されるのでしょうか?
実はクエリーリライトは、実行したSQL文とマテビューがちょっと違う場合に
も柔軟に、少し懐かしい言葉で言うと「ファジー」にクエリーをリライトして
くれます。
例えば、deptnoを追加した以下のようなマテビューを作成し、
■create materialized view mv_rewrite enable query rewrite as SELECT job,
deptno, sum(sal) sum_sal FROM emp GROUP BY job, deptno;
以下のように問合せをした場合、
■SELECT job, sum(sal) sum_sal FROM emp GROUP BY job;
作成したMV_REWRITEを利用してリライトされます。DBMS_MVIEW.EXPLAIN_REWRITE
で確認してみましょう。
SQL> EXEC DBMS_MVIEW.EXPLAIN_REWRITE('SELECT job, sum(sal) FROM emp GROUP BY job', statement_id => 'REWRITE_TEST2' ); SQL> select message from rewrite_table where statement_id = 'REWRITE_TEST2' order by sequence; MESSAGE --------------------------------------------------------------------- QSM-01151: 問合せはリライトされました QSM-01033: マテリアライズド・ビューMV_REWRITEで問合せがリライトされま した。
リライトされました!ってこれだけじゃよくわからないですね。。。
REWRITTEN_TXTという項目を見れば、どのようなSQL文にリライトされたかを確
認することができます。
SQL> select distinct rewritten_txt from rewrite_table where statement_id = 'REWRITE_TEST2'; REWRITTEN_TXT ---------------------------------------------------------------------- SELECT MV_REWRITE.JOB JOB,SUM(MV_REWRITE.SUM_SAL) SUM(SAL) FROM SCOTT. MV_REWRITE MV_REWRITE GROUP BY MV_REWRITE.JOB
マテビューで集計されたSUM_SALをさらにSUMで集計したものにリライトしてい
ます。
と、このように、問合せしたSQL文がマテビューを利用することができれば、
「ファジー」にリライトしてくれます。
また、以下のようなSQL文も同様にリライトされます。
■SELECT job, deptno, sum(sal) sum_sal FROM emp where deptno = 10 GROUP BY job, deptno; ■SELECT job, deptno, sum(sal) sum_sal FROM emp where deptno In(10, 20) GROUP BY job, deptno; ■SELECT job, deptno, sum(sal) sum_sal FROM emp HAVING sum(sal) > 100 GROUP BY job, deptno;
ここまでなら十分想定可能だと思います。
では、以下のような場合はどうでしょうか!?
■マテビュー(dept表を結合してdeptnoを表示)
create materialized view mv_rewrite enable query rewrite as
SELECT job, d.deptno, sum(sal) sum_sal FROM emp e, dept d
where e.deptno = d.deptno GROUP BY job, d.deptno;
■問合せ(dept表のdnameを表示)
SELECT job, d.deptno, d.dname, sum(sal) sum_sal FROM emp e, dept d
where e.deptno = d.deptno GROUP BY job, d.deptno, d.dname;
問合せには、マテビューにはないdnameが追加されています。
このSQL文はリライトされるのでしょうか?
続きはまた来週!
チョコで指輪のわらしべ長者、斬り! 恵比寿にて。