ワークスINDEXへ
オプティマイザヒントを使用したパフォーマンスチューニング-2
2005/11/23
■よく見かける 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へ