Tallman

技術とか読書とかいろいろ

SQL実践入門を読みました

SQL実践入門──高速でわかりやすいクエリの書き方 (WEB+DB PRESS plus)

SQL実践入門──高速でわかりやすいクエリの書き方 (WEB+DB PRESS plus)

SQLアンチパターンや失敗から学ぶRDBの正しい歩き方を読んでいて、ウインドウ関数や結合などまだまだ浅い理解だなーと思って買いました。
以下、気になったことと感想を書きます。

where句で条件分岐するのは素人、プロはSELECT句で条件分岐する。

どういうことかというと 例えば 名前、性別、部署を持つテーブルがあったとして

社員名簿テーブル

名前 性別 部署
太郎 営業
花子 営業

男性と女性人数を部署ごとに出したいとき whereを使うと

SELECT  部署, 
COUNT(*)
FROM 社員名簿
WHERE 性別= ''
GROUP BY 部署;

SELECT  部署, 
COUNT(*)
FROM 社員名簿
WHERE 性別= ''
GROUP BY 部署;

という感じでUNION使っても二回テーブルスキャンしなくてはいけないところを

SELECT  部署, 
  SUM( CASE WHEN sex = '' THEN 1 ELSE 0 END),
  SUM( CASE WHEN sex = '' THEN 1 ELSE 0 END)
FROM 社員名簿
WHERE 性別= ''
GROUP BY 部署;

というように書くことができます CASE式はWHENに当てはまればそこで評価を終了するので先程のWHERE句での分岐より処理も早いです。

Joinの際に駆動表はなぜ小さくするのか

ネステッドループで結合する際に、駆動表はフルテーブルスキャンが行われますが内部表はインデックスが使われます。
どうせフルテーブルスキャンするなら小さいほうが良いし、大きなテーブルスキャンするならインデックス使ったほうが良いので、駆動表は小さいほうがいいんですね。
ハッシュで結合するのは結合するテーブルが同じくらい大きいサイズのときにも有効ですが、メモリを大量に消費するので注意ともありました。

ぐるぐる系とガツン系

ぐるぐる系というのはいわゆる繰り返し処理(ループ)のことです。 一行ずつレコードを引っ張ってきて簡単な処理する、という行為のことですね。
対してガツン系はCASEやウインドウ関数等を駆使して処理を一回で記述してしまうことです。
シンプルでトランザクションの制御が容易だが、チューニングしにくくパフォーマンスもでにくいぐるぐる系と、チューニングしやすくパフォーマンスもでやすいが、トランザクションの制御やオプティマイザに委ねる部分が大きいガツン系か、そのトレードオフを認識する必要があるとのことです。
もともとSQLはループをできるだけ排除したい、という思想の元で生まれたそうで、手続き型言語になれている人ほど処理を全部自分で書いてループさせがちなので、ガツン系のメリットをしっかり知っておくのが重要です。

インデックスが使えないとき、役にたたない時

「失敗から学ぶRDBの正しい歩き方」のありましたが、

  • IS NULL

  • 列に直接演算

これらで検索するときはインデックスが使えません。
なぜかというと、インデックスの中に存在する値はあくまでそのセルの中にある値であって、演算後の値でも、NULLでもないからです。
選択率が高い(取り出すレコードがテーブル全体に対して割合が高い)ときも要注意です。

感想

SQLの当たり前に使われている用語に対して説明、考え方が乗っている良書でした。
ウインドウ関数や結合についてはなんとなくで使っていることが多かったので、クロス結合やパーティショニングのカットのイメージから説明してくれる本書はありがたかったです。 また全体を通してトレードオフというものを意識して書かれてあるとも感じました。
それぞれのアルゴリズムや手法にメリットデメリットが書かれていて、それを把握した上で活用するのが大事だということが繰り返し述べられていた印象です。