15
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Oracle】WITH句の問合せを一時表にする方法

Posted at

WITH句で問合せを定義しても、そのWITH句の問合せの利用箇所が1カ所のみの場合には、
オプティマイザーが気を利かせて一時表にせずに、本体の問合せとマージされた実行計画が作られる場合があります。

解決方法

WITH句のQueryごとに /*+ materialize */ ヒントを埋め込む。

なお「_with_subquery」という隠しパラメータも11gから追加されていて、
ALTER SYSTEM、ALTER SESSION、または、opt_param('_with_subquery' 'materialize') をヒント句に仕込んでSQLごとにどのようにWITHのQueryの挙動を操作できるようになっているようですが、
試したところ上手くいかず。(パターンは以下の3パターン)
今回は、WITH句ごとに materializeヒントを埋め込む対応を取りました。

なぜ一時表にする必要があったか?

今回この対応をしたのは、テーブル(マスタ系データ)の名称どうしの中間一致での結合でのパフォーマンス対応がきっかけでした。
LIKE結合(Table1.col_name1 LIKE '%' || Table2.col_name2 || '%')
をしていて、非等価結合だと結合方法がNL結合になってしまうため(HASH結合、SORT-MERGE結合は選択されない)、結合する対象データ(今回はTable2のデータ)の件数をあらかじめ絞り込んでおいたほうが、NL結合での対象件数がへって、結果として処理の時間の短縮に繋がります。
そのためTable2の件数をあらかじめ絞り込んでおいた一時表を、WITH句をわざと使用して作成しようとしたのですが、ヒントなしではオプティマイザによって最適化されて一時表が作成されず意図した実行計画にならなかったという経緯です。

参考

materialize
http://www.dba-oracle.com/t_materialize_sql_hint.htm
_with_subquery
https://dioncho.wordpress.com/2009/02/09/_with_subquery-parameter-controlling-subquery-factoring/
http://www.orafaq.com/parms/parm2088.htm

15
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?