【SQL】EXISTS句の中は"SELECT *" か"SELECT 1"か
備忘を兼ねて。
「SQLを実行する際、"IN"を使うよりも"EXISTS"を使う方が速い」
というのは割と周知の事実ですが、
じゃあ、EXISTSを使う場合、
「その中身は"SELECT *"を使うべきなのか"SELECT 1(定数)"を使うべきなのか」
というと、こっちは少々微妙な問題のようです。
//遅い SELECT * FROM tbl_A WHERE tbl_A.col_a IN (SELECT col_b FROM tbl_B); //速い SELECT A.* FROM tbl_A as A WHERE EXISTS (SELECT * FROM tbl_B as B WHERE A.col_a = B.col_b);
というのも、DBMSごと(さらに言えばVersionごと)に、どっちが速いかが変わってくるようなんですね。
簡単に調べてみた感じだと、だいたいこんな感じ。
DBMS | どちらが速いか |
---|---|
oracle以外 | "SELECT *"の方が速い |
oracle(9i以前) | "SELECT 1"の方が速い |
oracle(10g以降) | "SELECT *"の方が速い |
※oracle以外のDBMSでも定数使う方が速いものもあるとは思いますが(特に古いもの)、
その辺は調べきっていないので、上の表はあくまでも「だいたい」です。
正確にはoracleのバージョンと言うよりも、
ルールベースかコストベースかによってどちらが速いかが変わってくるようです。
いずれにせよ、今はoracleもほとんどコストベースで動かしていると思うので、
基本的には"SELECT *"が良いと思われます。
ただし、コストベースは時々意図しない動きをして気持ち悪いので、
対策として敢えてルールベースで動かしている場合などには"SELECT 1"のが速いです。
<参考>
SQLを速くするぞ
2つの副問い合わせの違い
まぁあれです。
古いソースを引き継いだ時に先任が"SELECT 1"って書いていたり、
また先輩から、「oracleは"SELECT 1"の方が速いからそうしろ」とか教えられたとしても、
それは決して嘘ではないので、温かい目と優しい心をもって修正しましょう。
終わり。