実行計画のキャッシュについて1 - 分岐を避けるSQL
かつて文字列連結をして、SQL文を構築していた時代がありました。
現在では ORM を利用することが多いかもしれません。
しかし、論理演算をしっかり理解して工夫すれば SQL だけで WHERE句などを分岐せずに作ることが可能です。
目次
分岐(IF文)か計算式か
私はプログラマ(設計者)の資質に「言い換えが巧いか」ということを重視しています。
例えば、消費税率が8%で非課税品があったとき、商品マスタの非課税品の税率項目に 0、課税品には 0.08 を登録しておけば、単純な計算で問題ありません。
しかし、慣れていないと日本語で仕様書を書くときに
非課税品フラグが1のときは、消費税を課税しない(消費税をゼロにする)
のように書き、これをそのまま分岐(IF文)で処理してしまう人が出てきてしまう。
日本語に限らず、
- 0を得たいときに、0 を掛ける
- 変化なしを得たいとき、1 を掛ける(で割る)
- 変化なしを得たいとき、0 を足す(を引く)
などの処理は、自然言語としては、「暗黙の変換が起きる」
つまり、消費税のように税率が0%と8%があるとすればよいところを、非課税品目と課税品目という風に表現されます。
そのため、「その逆の暗黙の変換」
つまり、非課税品目とは「税率が0%である」と言い換えができるか、というのはIT技術者にとって非常に重要な資質だと考えている訳です。
論理演算について
sikushima.hatenablog.comでも書きましたが、基本的に
と置き換えて考えて問題ありません。
展開、因数分解も数式と同じになります。
例えば数式で、展開した式と、因数分解した式は、
(a × b) + (a × c)
= a × (b + c)
掛け算を AND 、足し算を OR に置き換えた論理式も同様になります。
(a AND b) OR (a AND c)
= a AND (b OR c)
日本語の例としては、
男性で日本人、または、男性でアメリカ人
男性で、日本人、または、アメリカ人
日本語に限らず、自然言語(特に日本語は)を因数分解すると、最初の「男性で、」が、どこまでに掛かっているのか分かりにくく間違いのもと(例えば、『牛乳があれば』というジョーク)になりますが、理屈は同じです。
これが、(思考の上、自然言語、ソースコード)スラスラできていない人のソースコードは、ネストが深くなり、くどくて非常に読みにくくなってしまいます。
分岐を避けるSQL
もちろん、SQLでも同じで、他の言語と比べるとSQLには分岐がないため、この応用が特に重要になります。
ちゃんと理解していれば、スライドの通り、分岐をしてWHERE句を動的生成する必要はありません。
(……OR NULL IS NULL)
つまり、
(……OR True)
となると、カッコの内側にどんな条件があっても、必ず、Trueになりますから、カラムの内容を確認する必要がない訳です。
パースが必要(実行計画のキャッシュが使えない)
一つのSQLで複数の実行計画になるということは、実行計画のキャッシュが使えないということになります。
商用サーバでは実行計画をキャッシュしていますので、それが使えないのはいただけないですね。
次回は、実行計画のキャッシュの違いと、提案について書きます。