存在が変わる程の 夢を持ってみたくなる

2019/01/07

投げっぱなし

近畿では筋肉体操ない…だと…。ごきげんよう。

SQLのEXISTS句に今まではもっぱら SELECT 1 と書いてたんですが、
ウェブ上のサンプルや他の人のコードを見ると SELECT 'X' など
文字列のケースが多くてどっちがいいんだろう、と。
SELECT * か定数かという議論はすでになされていて、 * にすると
DBMSが自動で最適化するので速いとか、反対に意図しない動作を
防ぐ目的で定数にするなどの意見が挙がっています。

では定数の中では何がよいでしょうか。パフォーマンスに差が
あるのかどうかも含めて考えてみたいと思います。以下長文。



まず、自分が SELECT 1 を好んで使っていた理由は3つあります。

  1. 文字列よりも数値のほうがレスポンスが速そう
  2. trueの代替表現
  3. 多くの人が同じ値を選びそう

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' に宗旨替えすべきか脳内会議した内容から推測される
理由としては以下が思いつきます。

  1. 暗黙のキャストが発生するのを防ぐ

型が異なる値の比較やカラムへの代入を行うと、暗黙の型変換が
発生してパフォーマンスが低下するという注意点があります。
数値型と文字列型のような場合だけでなく、数値型同士であっても
浮動小数点型とNUMBERとの違いなどによってキャストされます。
文字列型の固定値を使えば、この暗黙の型変換が発生する可能性を
少しでも減らせる…かもしれません。想像の域を出ませんが。

というわけで、パフォーマンスに影響する可能性のある選定理由は
双方の 1. のみで、その効果も観測できるかどうかもわからないほど
不透明ですから、やはり好みの書き方でってことで…。 ←結論

ソーシャル/購読

X Threads note
RSS Feedly Inoreader

このブログを検索

ブログ アーカイブ