ワークスINDEXへ
オプティマイザヒントを使用したパフォーマンスチューニング-2  2005/11/23
以前書いた、オプティマイザヒントを使用したパフォーマンスチューニング の補足です。
若干逡巡の末w、私的「キラーヒント」をご紹介します。

■よく見かける index ヒントの間違った使い方

ソースの中に index ヒントが書いてあって、 それがコメントアウトされているのをよく見かけます。
コメントアウトされた理由としては、
 
・夜間バッチでアナライズしたら速くなったので取った
・思いの外、速くならない(却って遅くなった)ので取った
・ポリシーとしてヒントは使わない事になったので取った
 
のどれか、という事になるでしょう。
 
前回も書いたとおり、オプティマイザヒントは単なるコメントですから、 何を書いても(構文間違いや存在しないオブジェクトを指定しても) エラーになりません。
 
これも前回書いた事ですが、indexヒントで多い間違いは、
 
「テーブルのエイリアス(別名)を指定している時は ヒントに書くテーブル名もエイリアス」
 
の原則が守られていない場合でしょう。
 
select 
*
from ksale s
where ...
と書かれている場合は
 
select /*+ index(ksale PK_KSALE) */
ではなく
 
select /*+ index(s PK_KSALE) */
と、指定してください。

■そもそも index ヒントはキラーソリューションなのか

これも前回書きましたが、オプティマイザヒント自体、 万能なキラーソリューションという訳ではありません。
indexやall_rowsなどを付けて速くならなかったら諦める、 と言うのは、とりあえずな対応としては健全と言えなくもないのです。
 
その「とりあえず付けると速くなるかも」ヒントの中に、use_nl ヒントを加えてみてください。
個人的には、index よりも、こちらの方が「キラーヒント」だと思っています。
 
「indexを使っていないから遅い」
 
これは確かな事かもしれませんが、
 
⇒「全表走査(disk read多発)同士の結合になっている」
⇒「その結合方法は?」
⇒「HASH JOINやMERGE JOINを選択している」
 
と言う大元の理由があるはず。
ここを制御してやらないと、indexヒントを使っても「効かない」か「全索引走査」 するかで終わってしまいます。
 
実行計画上、HASH JOINやMERGE JOINになってしまった結合に対して、 use_nlを指定してあげると、「適正な索引が作成済み」、「アナライズ済み」、 「カーディナリティ高い」の条件を満たしていれば、 経験則では、索引を使った INDEX RANGE SCAN か INDEX UNIQUE SCAN まで補完してくれる場合が多いのです。

■use_nl 以外のキラーヒント

use_nl以外にもうひとつ。
 
"OR" や "IN (a,b,c, ...)" を使った時に MERGE JOIN(CARTESIAN)で、 直積されてしまう場合があります。
チューニング慣れしている人であれば、ため息をつきながら「UNION ALL」 を使って冗長なSQLに修正していくところですが、 ここで use_concat を使うとオプティマイザの方で勝手に、 「UNION ALL で書かれたもの」と判断してくれます。

■実機で実測、これ基本

何度も繰り返し言ってしまいますが、言うまでもなく、上記に書いた事は、 どんな場合でも万能ではありません。
ヒントを入れたら却って遅くなる事も当然ありますので、 実行計画やトレースの見方がわかる人はともかく、 そうでない人にはそれなりのリスクがある事をご了解ください。
 
まあ、普段から「遅かったら index ヒントを入れてみて、速くならなかったら 諦める」 方式のソリューション?を採用している人(かつての私もそうでしたw)は、 お試しを。
 
また、ヒントに限らずSQLチューニングは「問題の起こっている実機で」 確認するのが基本です。

ワークスINDEXへ