SQL

「等しい」と「重複している」の違い。それらとUNIQUE制約の関係

SQL

SQLを使っていると、あたかもNULLがNULLに等しいかのように見える場面が多々ある。 例えば DISTINCT や GROUP BY で複数のNULLが1個に集約されるとか。あるいは集合演算子(UNION, EXCEPT, INTERSECT)でのNULLの扱いとか。 SQL92の解説書標準SQLガイド (アス…

「NULLがUNIQUE制約に縛られないことを利用する」のは、正当なNULLの使い方

SQL

リンク先は「UNIQUE INDEXを振った列に複数のNULLを投入できること利用して、ユニークであるべきユーザIDの使い回し(=退会したユーザのIDを新規ユーザに開放する)を実現する」という話。 アクティブなユーザ名はユニークにしたいけど削除されたユーザの情報…

「索引列を演算するとインデックスが使えなくなる」これはなぜなのか

例えばテーブルt1の列col1にインデックスがあり、以下のクエリでそのインデックスが参照される場合、 select * from t1 where col1 >= 20 --(1)クエリを以下のように書き換えると select * from t1 where col1*5 >= 100 --(2)インデックスが使えなくなってし…

忘れてしまったほうがいいSQLチューニングテクニックについて

SQL

10年ぐらい前はJavaで文字列を連結するときは String ではなく StringBuffer を使ったほうが速いなんて言われてたんだけど、それがテクニックとして有効だったのは「StringBufferを使えばこれこれの内部動作になる」という関係が固定されていたからで、仮にJ…

union allがデフォルト。unionは特殊な場合のみ使う

SQL

重複行を削りたいならunionを使う。重複行を生かしたいならunion allを使う。 ここまではよいとして、どっちでもよい場合、例えば 重複行があり得ない場合 IN句のサブクエリなので重複行があってもなくても結果に影響しない場合 にどうするか。 以前はunion…

日常用語でnullを理解する(2)

SQL

SQLにおけるnullは「値があることは分かっているが、それが何なのかはわからない」という意味だ。 「値がない」という意味ではない、ということに注意しなくてはならない。 nullは「値がない」ではない nullを「値がない」という意味だと考えてしまうと、 'a…

日常用語でnullを理解する(1)

SQL

セルコの本なんかには、nullを参照するSQLが直感に反する結果を返すことがあると書いてあるのだが、3値論理は「論理」というぐらいだから人間にとって*常に*不可解なものであるはずがないし、だったらnullがらみのSQLの挙動を直感的・日常的な用語だけで(=…

クラスタリングファクタによってSQLのパフォーマンスが変わる話

SQL

昨日の実験では、両側にインデックスがある場合、マージ結合とネスト化ループ結合の速さがハッシュ結合と同等かそれ以上になってしまった。 少量のマスタと大量のトランザクションの結合は、ハッシュ結合が圧勝してしかるべきなので何だこりゃと思ったのだが…

結合方式とインデックスの関係

SQL

ネスト化ループ結合/マージ結合/ハッシュ結合は、それぞれインデックスをどのように使うのか、を整理する。 マスタのxxコードとトランザクションの同名の列を等結合にするSQLについて、 インデックスが片側(マスタ側のみ) インデックスが両側 インデックス…

select * は禁じ手で、必ず列名を列挙すべしとされている理由

SQL

select * from ... と書いてはダメ、たとえ全列取得する場合でも select a, b, c, d from ... と書くのが常識、という話をずいぶん前に聞いたことがあって、意味がわからないので人力検索に投げてみた。 いただいた回答を整理しておく。 テーブル内の一部の…

INをEXISTSに書き換えると速くなるサンプルSQLを作るのは難しい

SQL

「INをEXISTSに書き換えると速くなる」という話が、DBMSやそのバージョンを限定せずにSQL一般の話として語られることがあるけど、実感としてそれはないだろうと。 そこでどういう場合に速くなるのか確認しようと思ったけどうまくいかなかったので、どういう…

Nested Loop結合は、実際にはネストしたループではない

SQL

某書を読むと、Nested Loop結合がこう説明されていた。 どのような場合でも適用できる反面、高い性能を得るのは難しい。 以降で述べるような、より効率の高いほかの方法が使えない場合にこの方法を使うことになる。 ... ネストループ結合では、それぞのテー…

except all 演算子

union all の except 版。 重複する行が、引かれる方の集合に2行、引くほうの集合に1行あったら、演算結果に1行残す。

group byの注意点

SQL

今日、こんな感じのテーブルを作って、毎晩日次売上を月次売上に足しこむバッチを走らせる、という仕事をした。 ●店舗別日次売上 create table daily ( store_id integer not null primary key, -- 店舗ID store_group_id integer not null, -- 店舗が所属す…

重複行があり得ないクエリに付加した distinct にもコストがかかる

C.J.Dateに倣って、重複行があろうとなかろうと、selectには常に distinct を付けるというやり方でイケルのかどうか、試してみた。 動的にSQL文を組み立てる場合、必要な時だけ distinct を付加するのが面倒くさいので、付けっぱなしにできるとありがたいの…

SQLの集約関数はnullの列を無視する

sum(), avg(), max(), min(), count(列名) は、nullの列を無視する。 特にavg()に注意。引数の列にnullがありえる場合は、合計の除数が期待しているものと違ってしまわないか注意する。 (ありがとうございました>ss2004さん)