こんにちは、さるまりんです。
SQLを書いていると、
「このSQL、重いですね〜」
と言われたり、
「インデックスを貼っていますか?」
なんて言われることがあります。
考えないといけないことではあるのですが、
- データベースがどうやってデータを探しているのか
- なぜ速いSQLと遅いSQLがあるのか
を意識するのは、少し後になってからなんですよね。
そんな時に役立つのが EXPLAIN です。
今回は、EXPLAINを使ってデータベースがどんなことを考えているのかを、ちょっと覗いてみたいと思います。
EXPLAINとは?
一言で言うと、
SQLをどのように実行しようとしているかを見るための機能
です。
例えば次のSQLがあります。
SELECT *
FROM users
WHERE id = 1;
「idが1のユーザーを取得するSQL」です。
もちろんそれで間違いないです。
でも、データベースはその前に、
どうやって探そうかな?
ということを考えています。
EXPLAINは、その考えている内容を見せてくれる機能なんです。
データベースは作戦を立てている
例えば本棚を想像してみてください。
本が10冊しかなければ、最初から順番に見ていってもすぐに見つかります。
でも100万冊あったらどうでしょう。
順番に探していたら大変です。ものすごい時間がかかりますよね。
そこで、
- ジャンルごとに分ける
- 索引を使う
- 並び順を工夫する
といった方法を考えます。
データベースも同じです。
データが少ない時と多い時では、効率の良い探し方が変わってきます。
そしてデータベースは、どの方法が良さそうかを考えてからSQLを実行してくれます。
実際にEXPLAINを使ってみる
今回はPostgreSQLを例にします。
ただし、考え方そのものは多くのデータベースで共通です。
まずはテーブルを作ります。
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name VARCHAR(100)
);
データを入れてみます。
INSERT INTO users
SELECT
generate_series,
'user_' || generate_series
FROM generate_series(1, 10000);
そしてEXPLAINを実行します。
EXPLAIN
SELECT *
FROM users
WHERE id = 5000;
結果は環境によって多少異なりますが、例えば次のような内容が表示されます。
Index Scan using users_pkey on users
ここでは細かい意味までは入りません。
まずは、
Index Scan が使われている
ということだけ見てみましょう。
これは、
インデックスを使って探そうとしている
という意味です。
データベースが効率の良い探し方を選んでくれていることが分かります。
インデックスがなかったら?
今度はインデックスのないテーブルを作ってみます。
CREATE TABLE users_no_index (
id INTEGER,
name VARCHAR(100)
);
同じデータを入れます。
INSERT INTO users_no_index
SELECT
generate_series,
'user_' || generate_series
FROM generate_series(1, 10000);
そして同じように実行してみます。
EXPLAIN
SELECT *
FROM users_no_index
WHERE id = 5000;
すると、
Seq Scan on users_no_index
のような結果になることがあります。
SeqはSequentialの略です。
順番に読むという意味ですね。
つまり、
とりあえず最初から見ていこう
という作戦を選んでいることになります。
データが少なければ問題ありませんが、データが増えてくると時間がかかる可能性があります。
順番に探していくため、探す範囲が広くなるほど時間もかかりやすくなります。
EXPLAINを見ると何が分かるの?
EXPLAINを見ることで、例えば次のようなことが分かります。
- インデックスが使われているか
- テーブルを順番に読んでいるか
- JOINをどのような順番で実行しているか
- データベースがどんな作戦を選んだか
実際の開発では、
「SQLが遅い」
という話になった時にEXPLAINを見ることがよくあります。
私がEXPLAINを見る時
私の場合、SQLの結果がおかしい時よりも、SQLの動きが気になる時に使うことが多いです。
例えば、
- JOINを増やした時
- インデックスを追加した時
- データ量が増えてきた時
などです。
SQLを書く時は結果ばかり見てしまいがちですが、EXPLAINを見ると、データベースがどんな考え方で動いているのかが少し見えてきます。
まとめ
EXPLAINは、SQLを実行する前にデータベースが考えている作戦を見るための機能です。
最初は表示内容が難しく見えるかもしれません。
でも、
- データベースは作戦を立てている
- EXPLAINはその作戦を見るためのもの
ということだけ覚えておくだけでも、データベースの扱いに強くなると思います。
SQLを書くことに慣れてきたら、次はデータベースがどう考えているのかも考えてみると面白いかもしれません。
私自身も、
「SQLが遅くなってから見る」
ではなく、
「気になったら見てみる」
くらいの気持ちでEXPLAINと付き合っていきたいなと思っています。
読んでくださってありがとうございました。
それでは、また!