SQL は、リレーショナルデータベースのデータを操作するための言語です。Structured Query Language の略で、MySQL や PostgreSQL をはじめ、製品が違っても基本の書き方は共通しています。
書く順番と、実行される順番は違う
SQL でつまずく原因の多くが、ここにあります。SELECT から書き始めますが、データベースが処理する順番は SELECT が後ろの方です。PostgreSQL の公式ドキュメントは、評価の順序を次のように説明しています。
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
これが分かると、初心者が必ず一度は踏む次の挙動に説明がつきます。
-- これは動かない
SELECT price * quantity AS total
FROM order_items
WHERE total > 10000;
WHERE が処理される時点では、まだ SELECT が計算されていないので total という名前は存在しません。公式も「出力列の名前は ORDER BY と GROUP BY では使えるが、WHERE と HAVING では使えない」と明記しています。書き直すならこうなります。
SELECT price * quantity AS total
FROM order_items
WHERE price * quantity > 10000;
同じ理由で、ORDER BY では別名が使えます。エラーになるかどうかが句によって違うのは、気まぐれではなく処理の順番の結果です。
遅いときに最初に見るところ
一覧が遅い、という相談で実際に効くのは次の順です。
- 絞り込みに使っている列に索引があるか。 索引が無いと、行数が増えた分だけ素直に遅くなります
- 索引があるのに使われていないか。 列に関数を当てたり型が食い違ったりすると、索引は使われません
- 同じ問い合わせが何度も飛んでいないか。 1件ずつ引く形になっていると、件数に比例して回数が増えます(ORM 経由で起きやすい形です)
3番目は SQL 単体を眺めていても気づけません。発行された問い合わせの回数を見る必要があります。
ORM を使っていても読めた方がよい理由
ORM があれば SQL を書かずに済む場面は多いですが、読めないと困るのは問題が起きたときです。遅い、件数が合わない、想定と違う行が消えた、といった状況では、最終的に発行された SQL を見るのが最短になります。
書けることより、発行された SQL を読んで何をしているか分かることの方が実務では先に必要になります。
よく一緒に出てくる用語
- 橋渡しをする ORM
- まとまりを保証する トランザクション
- 代表的な製品の MySQL と PostgreSQL
- 性能面の考え方はRDBMSの性能チューニングの基本