X

オラクルエンジニア通信では、オンプレミスからクラウドまで、オラクルテクノロジーの最新情報をお届けします

Oracleのオプティマイザが問い合わせ処理を最適化する方法~ソースコードを書いているエンジニアが語る

RDBMS にとってクエリ・オプティマイザは、最も重要なコンポーネントの一つですが、その動作についてはあまり知られておらず、ブラックボックスだと思われている方が多いようです。

このコラムでは、Oracle の開発部門で、オプティマイザのソースコード修正を担当している立場から Oracle Database のオプティマイザの基本動作や機能、歴史について紹介していきます。




どうやって問い合わせ処理を最適化するのか?

前回の「Oracleのオプティマイザとは何か?」では、オプティマイザが担う役割についてお話しし、「どうやって問い合わせ処理を最適化するのか?」という問いで終わっていました。

今回は、この問いに回答すべく Oracle Database のオプティマイザの構成要素について見ていきます。

オプティマイザが、問い合わせ処理を最適化する方法を大別すると、以下の2つに分けることができます。

1. 問合せの変換(Query Transformation)

Query Transformation は、入力されたSQL文を論理的に同じ意味を持たせたまま、SQL文自体をより効率的な文に変換する機能です。

Query Transformation には、Predicate Transformation や Common Sub-expression Elimination (CSE), Order-BY Elimination (OBYE), Outer Join Elimination (OJE), Simple View Meging (SVM), Predicate Move around (PM), Complex View Merging (CVM), Sub-query Unnesting (SU), Join Predicate Push Down (JPPD) さらには OR Expansion, Star Transformation (ST) など様々なものがあります。

・・・と、このように列挙されても、どうやって最適化するのか、直感的に分かりにくいと思いますので、その一例として Predicate Transformation の一つである Transitive Predicate Generation について見ていきましょう。

下の例を見てください。このSQL文は、deptno が 10 である従業員名とそのロケーションを取り出す問い合わせです。

select e.ename, d.loc from emp e, dept d
where e.deptno=d.deptno and e.deptno=10;

変換前のこの文を処理するには、emp 表から deptno=10 に該当する行を一行取り出し、dept 表から d.deptno=10 を満たす行を探して結合するという処理を emp 表の deptno=10 を満たす行の数だけ繰り返します。つまり、emp 表に deptno=10 を満たす行が10行あった場合、10回 dept 表を探すことになります。dept 表に20行のデータがあった場合は、その探索コストは最大10回*20行=200になります(結合方法はネステッド・ループ結合だと仮定)。

このSQL文に Transitive Predicate Generation を適用するとSQL文は以下のように書き換えられます。

select e.ename, d.location from emp e, dept d
where e.deptno=d.deptno and e.deptno=10 and d.deptno=10;
^^^^^^^^^^^

これにより、dept 表を前もって deptno=10 でフィルタリングすることができますので、結合コストは10回*1行=10(dept.deptno はuniqueだと仮定)と1/20に減らすことができます。コストが1/20になるということは、今まで処理に10分かかっていたものが30秒で終わるようなものですから、Query Transformation がいかに重要なのかを理解して頂けるのではないでしょうか。

注:厳密に言うと、この場合 dept 表は 1-row table になるため、dept 表が driving サイド(Outer Table)になり emp 表が probe サイド(Inner Table)に変わります。ですので、1回*10行=10 というコスト計算になります。また、ここでのコストは結合コストしか考慮していませんので、問い合わせ処理全体の時間が1/20になるわけではありません。

ただ、全ての Query Transformation が常に全てのSQL文に効果的なわけではありません。ですので、どのような時にどのような Transformation を適用すれば良いかを適切に判断するのがオプティマイザの役割になります。

2. アクセス・パス解析(Access Path Analysis)

Access Path Analysis は、Query Transformation 後のSQL文の各表へのアクセス方法(Access Path)や表同士の結合方法(Join Method)、結合順序(Join Order)を選択する機能です。

表へのアクセス方法には、全表スキャン(FTS)、ROWIDスキャン、索引スキャンなどが、表の結合方法には、ネステッド・ループ結合(Nested Loop Join)やハッシュ結合(Hash Join)、ソート/マージ結合(Sort Merge Join)があり、オプティマイザはその都度、最適なアクセス方法や結合方法を選択します。また、結合順序についても関連する表の適切な結合順序を決定していきます。

Oracle Database では、その役割から Query Transformation のことを Logical Optimizer、Access Path Analysis のことを Physical Optimizer と呼んだりします。

以上がオプティマイザの構成要素になりますが、これだけでは問い合わせ処理を最適化する方法論のみであり、具体的にどうするかがイメージできませんよね。特に「適切」や「最適」と表現している部分が謎ですよね。

いったい何を持って適切といえるのか?次回はこの点にフォーカスし、最適化のゴールについて述べたいと思います。






Oracle Database のソースコードを書いているエンジニアが語る "Oracle のオプティマイザ"


日本オラクル株式会社 Sustaining Engineering
真下 哲(ましも さとし)

製品のソースコード修正を担当する Sustaining Engineering 部門において、オプティマイザを担当する立場から、Oracle Database のコア機能であるオプティマイザについて語ります。


Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
Oracle

Integrated Cloud Applications & Platform Services