0Pricing
SQL Academy · レッスン

シーケンシャルスキャンとインデックススキャン

シーケンシャルスキャンで十分な場合、インデックススキャンが必要な場合、そしてプランナーがどのように判断するかを理解します。

「シーケンシャルスキャンとインデックススキャン」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。

行を見つける 2 つの方法

データベースには、行を読み取る基本的な方法が 2 つあります。

  • Sequential Scan — テーブルのすべてのページを読み取ります
  • Index Scan — インデックスをたどり、一致する行を取得します

Sequential Scan が適している場合

テーブルの大部分が必要な場合は、インデックスを読み取り、さらに一致する各行を取得するより、テーブルをスキャンする方が安価です。おおよその目安は、行の約 10〜20% を超える場合は seq scan が有利です。

Index Scan が有利な場合

選択性の高いクエリ(行のごく一部だけを取得するクエリ)では、インデックスが効果を発揮します。

EXPLAIN SELECT * FROM users WHERE id = 42;
-- Index Scan using users_pkey  (cost=0.43..8.45 rows=1)

EXPLAIN SELECT * FROM users WHERE active;
-- Seq Scan on users  (cost=0.00..15000.00 rows=950000)
-- (because most users are active)

Index Scan と Index-Only Scan

必要な列がすべてインデックスだけに含まれていて、テーブルを取得する必要がない場合があります。これが Index-Only Scan です。

CREATE INDEX users_email_id_idx ON users(id) INCLUDE (email);

EXPLAIN SELECT email FROM users WHERE id = 42;
-- Index Only Scan using users_email_id_idx

Bitmap Index Scan

選択性が中程度の場合、PostgreSQL は一致する行のビットマップを作成し、物理的な順序で行を取得することがあります。これにより、ランダム I/O より高速になります。

EXPLAIN SELECT * FROM orders WHERE status = 'pending';
-- Bitmap Heap Scan on orders
--   Recheck Cond: (status = 'pending')
--   -> Bitmap Index Scan on orders_status_idx

Planner が Seq Scan を選ぶ理由

一般的な理由は次のとおりです。

  • 検索対象の列にインデックスがありません
  • インデックスを使用できません(列に対する関数、OR 句、型の不一致など)
  • 予想される行数が多く、インデックスを使うメリットがありません
  • 統計情報が古く、Planner が選択性を誤って判断しています

インデックスの使用を強制する場合の注意

PostgreSQL には直接ヒントを指定できません。代わりに次の方法を使います。

  • ANALYZE を実行して統計情報を更新します
  • 適切なインデックスを追加します
  • セッション設定を変更します。診断目的で SET enable_seqscan = off; を使用できます(本番環境では使用しません)

インデックスを使用できる述語

インデックスの効果を得るには、WHERE 句が「sargable」である必要があります。つまり、インデックス対象の列を直接比較します。

-- GOOD:
WHERE created_at >= '2024-01-01'

-- BAD (function on the column):
WHERE date_trunc('day', created_at) = '2024-01-01'

-- BAD (cast):
WHERE created_at::DATE = '2024-01-01'

-- FIX: add a functional index, or rewrite with range.

複合インデックスの順序

(a, b) に対するインデックスは、a 単独のクエリと a AND b のクエリには役立ちますが、b 単独のクエリには役立ちません。

インデックスのサイズが重要な理由

よく使うキーを持つ細い B-tree インデックスは、全体をメモリに保持できる場合がありますが、幅の広いインデックスでは難しいことがあります。小さいインデックスほど高速です。

プランを確認する

インデックスを追加したら EXPLAIN ANALYZE を実行し、Planner が実際に使用していることを確認します。使用されていなければ、原因を詳しく調べます。

まとめ

Sequential Scan と Index Scan の選択は、選択性によって決まります。

  • 選択性の高いフィルター → Index Scan
  • テーブルの大部分を取得 → seq scan
  • 中間の場合 → Bitmap Scan
  • sargable かどうかに注意します

確認問題

既存のインデックスがあるのに、PostgreSQL が Sequential Scan を選ぶのはなぜですか。

よくある質問

「シーケンシャルスキャンとインデックススキャン」レッスンは無料ですか?

はい。「シーケンシャルスキャンとインデックススキャン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。

「シーケンシャルスキャンとインデックススキャン」で何を学びますか?

シーケンシャルスキャンで十分な場合、インデックススキャンが必要な場合、そしてプランナーがどのように判断するかを理解します。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「シーケンシャルスキャンとインデックススキャン」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Academyレッスンでコードを書いて実行できますか?

はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. EXPLAINとEXPLAIN ANALYZEの読み方
  2. シーケンシャルスキャンとインデックススキャン
  3. Hash Join、Merge Join、Nested Loop
  4. 遅いクエリの特定と修正
← SQL Academyに戻る