JOINを使って表結合するとSQLが遅い!?


ここではORACLEデータベースのSQLで、JOINを使ったときの疑問について紹介します。

SQLの実行計画の見方や確認方法については↓で紹介していますので参考にしてください。
>>【ORACLE】SQLの実行計画の見方
>>【ORACLE】SQLの実行計画を取得する方法

今回の疑問

どうもORACLEでSQLを書いていてINNER JOINやOUTER JOINを使って表結合を行うと
WHERE句で単純に結合した場合よりも遅くなることがある気がします。
元々私はJOINではなく、(+)で外部結合していた世代なので、知識が不十分。

例えば下のようなSQLです。

select
a.id
,b.div_cd
,b.div_nm
from
table1 a
,table b
where
a.id = ‘100’
and a.div_cd = b.div_cd
;

これをJOINで書くとこんな感じ。というかこんな感じのプログラムがよくあります。
結果は変わらないのですが、どうも上のSQLよりも遅いことがよくあります。

select
a.id
,b.div_cd
,b.div_nm
from
table1 a
inner join table b
on (a.div_cd = b.div_cd)
where
a.id = ‘100’
;

SQLが遅くなる原因

あまりJOINのことを知らないので、あくまで仮説ですが
上の例だと「a.id = ‘100’」という条件の絞り込み前に、ONに書かれた条件で結合されているんじゃないだろうか。

というのも、ORACLEオプティマイザがSQLを評価するときの順序が、FROMが一番初めのはず。
ということはFROM,WHEREの順で評価されるのでWHERE句に書かれた「a.id = ‘100’」の絞り込み前に
FROM句のON「a.div_cd = b.div_cd」で結合されるような実行計画になっているのでは。

正解は、、、今度、実機検証してみます。

解決方法

解決方法は・・・
JOINを使わないこと!って書くと色々問題ありそうなので、JOINを使う場合に下記のような書き方にしてみることをオススメします。
ONの条件に「a.id = ‘100’」を追加してみましょう。
きっとこれで解決するパターンもあるはず。。

select
a.id
,b.div_cd
,b.div_nm
from
table1 a
inner join table b
on (a.id = ‘100’
and a.div_cd = b.div_cd)
;

最後に

最後までお読みいただきありがとうございます。

SQLのチューニングについては↓で詳しく解説していますので参考にしてください。
>>SELECT文のSQLチューニング方法まとめ