クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

インデックスで速く探す

このレッスンのあとで: インデックスがクエリを速くする仕組みを、説明することができる。

40分のレッスンコマンドなし

窓口で待たせる30秒

ある市役所の市民課では、申請のデータが30万件あります。

窓口で住民番号を入れると、画面が出るまで30秒かかります。後ろには列ができています。

システム担当の先輩が、ある列に「インデックス」を1つ作りました。すると、画面はすぐに出るようになりました。今日は、その仕組みを学びます。

このレッスンのゴール

メモ

インデックスがクエリを速くする仕組みを、説明することができる。

キーワード

ことばいみれい
インデックス列の値から行の場所を引ける索引です。
フルスキャン全部の行を順に読むことです。
実行計画データベースがどう探すかの予定です。
CREATE INDEXインデックスを作る命令です。CREATE INDEX idx_requests_resident ON requests (resident_no);
書き込み行を足したり、変えたり、消したりすることです。

学生が入力するセルは、このプレビューでは空白です。

索引がないと全部を読む

分厚い業務マニュアルで「有給休暇」を探す場面を考えます。

巻末の索引がなければ、1ページ目から順にめくるしかありません。

データベースも同じです。インデックスがない列で探すと、全部の行を読みます。これをフルスキャンといいます。行が多いほど、時間がかかります。

インデックスは並べた索引

インデックスは、列の値を順番に並べ、それぞれの行の場所を書いたものです。

並んでいるので、真ん中を見て「前か後ろか」を決められます。これをくり返すと、読む範囲が毎回半分になります。

30万件でも、およそ20回見るだけで目的の行に着きます。

例: 何件読めば見つかるか

申請の件数フルスキャンインデックス
1,000件最大1,000件約10回
30,000件最大30,000件約15回
300,000件最大300,000件約19回
3,000,000件最大3,000,000件約22回

学生が入力するセルは、このプレビューでは空白です。

実行計画で探し方を確かめる

EXPLAIN QUERY PLAN をクエリの前に付けると、データベースが探し方を教えてくれます。

SCAN と出たら、全部の行を読む予定です。SEARCH ... USING INDEX と出たら、インデックスを使う予定です。

遅いクエリを調べるとき、現場の担当者が最初に見るのがこの実行計画です。

試そう: インデックスなし

コード: sql
-- 住民番号で申請を探します。
SELECT * FROM requests WHERE resident_no = 'R-10482';

-- データベースが、どう探すつもりかを聞きます。
-- SCAN は「全部の行を順に読む」という意味です。
EXPLAIN QUERY PLAN
SELECT * FROM requests WHERE resident_no = 'R-10482';

試そう: インデックスあり

コード: sql
-- resident_no 列にインデックスを作ります。
CREATE INDEX idx_requests_resident ON requests (resident_no);

-- もう一度、探し方を聞きます。
-- SEARCH ... USING INDEX は「索引を使って探す」という意味です。
EXPLAIN QUERY PLAN
SELECT * FROM requests WHERE resident_no = 'R-10482';

-- WHERE の列を kind に変えると、探し方はどうなりますか。

インデックスにはコストがある

インデックスは、ただではありません。

行を足したり変えたりするたびに、データベースはインデックスも直します。そのぶん、書き込みが遅くなります。保存する場所も増えます。

だから、よく探す列や、JOIN でつなぐ列にだけ作ります。例えば、住民番号や外部キーの列です。

よくある間違い

注意

「インデックスは多いほど速い」と思う人がいます。これは読むときだけの話です。インデックスが増えると、申請を登録するたびの書き込みが遅くなります。よく探す列にだけ作り、使われないインデックスは消します。

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。