本文へスキップ
BecomeCoder

SQL テーブル設計 (DDL)コース · 第4章 検索を速くする · レッスン14

インデックス ― 検索を速くする索引

ブラウザで完結

導入

第0章で「10万行でも SQL なら一瞬」と言いました。でも実は、何も考えないと DB は「先頭から1行ずつ全部見る」しかありません(フルスキャン)。10万行なら10万回の確認です。これを劇的に速くするのが インデックス(索引) です。本の巻末索引と同じ発想で、「この値はここ」という早見表を別に持ちます。

説明

インデックスの効き方は、辞書を引くのに似ています。

flowchart TB
    subgraph NO["索引なし(フルスキャン)"]
        A["1行目を見る → 違う<br/>2行目を見る → 違う<br/>… 10万行目まで全部確認"]
    end
    subgraph YES["索引あり"]
        B["並べ替え済みの早見表で<br/>目的の値へ一気にジャンプ"]
    end
    NO -->|"CREATE INDEX で"| YES

インデックスは CREATE INDEX で作ります。「どの表の・どの列に索引を張るか」を指定します。

CREATE INDEX idx_users_city ON users(city);

これで WHERE city = '東京' のような検索が速くなります。SQLite には、クエリが索引を使うかどうかを見せてくれる EXPLAIN QUERY PLAN があります。索引を作る前後で見比べてみましょう。

-- 索引を作る前は SCAN(全部見る)と出る
EXPLAIN QUERY PLAN SELECT * FROM users WHERE city = '東京';

-- 索引を作る
CREATE INDEX idx_users_city ON users(city);

-- 作った後は SEARCH ... USING INDEX(索引で探す)に変わる
EXPLAIN QUERY PLAN SELECT * FROM users WHERE city = '東京';

万能ではありません。インデックスにはコストがあります。

  • 書き込みが少し遅くなるINSERT/UPDATE のたびに索引も更新するため。
  • 場所を取る… 早見表のぶんデータが増える。

だから「検索や結合・並べ替えでよく使う列」に絞って張るのが定石です。主キーには自動で索引が付きます。外部キー列(orders.user_id など、JOINON で使う列)は、索引の有力な候補です。

やってみよう

初期表示の EXPLAIN QUERY PLAN ... をまず実行し、SCAN users のような表示(全部見る)を確認しましょう。次に CREATE INDEX idx_users_city ON users(city); を実行し、もう一度同じ EXPLAIN QUERY PLAN を走らせて、表示が SEARCH users USING INDEX ... に変わることを見比べてください。索引が「探し方」を変えた証拠です。

演習

productscategory_id 列にインデックスを作ってください。名前は idx_products_category とします。

ヒント1を見る

CREATE INDEX 索引名 ON テーブル(列); の形です。

ヒント2を見る

CREATE INDEX idx_products_category ON products(category_id);

実際に動かしてみよう

下のエディタにクエリを書いて「実行」を押すと、ブラウザ内のSQLiteで結果が表示されます。本文の例をそのまま試したり、書き換えたりしてみましょう。

SQL — ブラウザ内で実行(SQLite)

ブラウザ内でSQLを動かす環境(SQLite)を読み込みます(初回のみ一瞬)。
スクロールして表示された時点でも自動で読み込まれます。