SQLのEXISTS句に今まではもっぱら SELECT 1 と書いてたんですが、
ウェブ上のサンプルや他の人のコードを見ると SELECT 'X' など
文字列のケースが多くてどっちがいいんだろう、と。
SELECT * か定数かという議論はすでになされていて、 * にすると
DBMSが自動で最適化するので速いとか、反対に意図しない動作を
防ぐ目的で定数にするなどの意見が挙がっています。
では定数の中では何がよいでしょうか。パフォーマンスに差が
あるのかどうかも含めて考えてみたいと思います。以下長文。
まず、自分が SELECT 1 を好んで使っていた理由は3つあります。
- 文字列よりも数値のほうがレスポンスが速そう
- trueの代替表現
- 多くの人が同じ値を選びそう
1. はただの若かりし日の勘違いというか若気の至りなんですが、
普通のカラムを検索するときもVARCHAR2よりもNUMBERのほうが
検索速いじゃないですか。何となく。(そこはアバウトなんだ…
それにならってというかあやかって、固定値に数値を返すのが
一番応答が速いんじゃないかという思い込みがありました。
2. は、EXISTS句、というかWHERE句の条件は真偽を返しますので、
それをわかりやすく見せたいという思いからです。
EXISTSの中の副問い合わせが真を返す、と明示的に書くことで、
EXISTS句全体が真偽を取ることをたとえばSQLに詳しくない人に
理解してもらうねらいがあります。
いや誰向けにコード書いてんのって話ですが…。
仮にSQLにtrueという定数が存在していればそう書いたのですが、
DBMS依存ですので代わりに 1 が最もふさわしいと考えました。
整数値の 0/1 はフラグの値など、言語にブール値がない場合に
false/true の代わりとしてよく用いられます。
例外としてC言語はif文の条件式の値が0ならば真、0以外ならば
偽と判断するので値が逆ですがそれはさておき。
それだったら文字列で 'true' ならさらにわかりやすいのでは、
と思われるかもしれませんが、そこで理由 3. が関係してきます。
文字列だと人によって表記揺れが発生しがちです。
サンプルで最も多いXだって 'X' と 'x' の2通り見られました。
バインド変数で与えない限りこれらは別のSQLとして扱われます。
そうでなくてもぼくなんか何でもいいって言われるとどれだけ
変なこと書こうかとわくわくしてしまうというのにー。(知るか
そこで整数に絞ってしまえば、 SELECT 2 とか 100 とか 0 とか
書くひねくれ者は少なくて、多くの人が 1 と書くでしょうから、
コードの統一性が保たれることが期待できます。
では文字列派の主張はどのようなものでしょうか。
自分が 'X' に宗旨替えすべきか脳内会議した内容から推測される
理由としては以下が思いつきます。
- 暗黙のキャストが発生するのを防ぐ
型が異なる値の比較やカラムへの代入を行うと、暗黙の型変換が
発生してパフォーマンスが低下するという注意点があります。
数値型と文字列型のような場合だけでなく、数値型同士であっても
浮動小数点型とNUMBERとの違いなどによってキャストされます。
文字列型の固定値を使えば、この暗黙の型変換が発生する可能性を
少しでも減らせる…かもしれません。想像の域を出ませんが。
というわけで、パフォーマンスに影響する可能性のある選定理由は
双方の 1. のみで、その効果も観測できるかどうかもわからないほど
不透明ですから、やはり好みの書き方でってことで…。 ←結論
0 件のコメント: