PostgreSQLでSeq Scanが発生してもインデックス追加が正解とは限らない理由|実行計画から判断する方法

PostgreSQL

PostgreSQLでSQLの性能調査をしていると、実行計画にSeq Scan(シーケンシャルスキャン)が表示されることがあります。しかし、Seq Scanが発生しているという理由だけで、すぐにインデックスを追加するのは適切とは限りません。この記事では、PostgreSQLがSeq Scanを選択する理由や、インデックス追加を判断するために確認すべきポイントについて解説します。

Seq Scanとは何か

Seq Scanとは、PostgreSQLがテーブル全体を順番に読み取る検索方法です。テーブルの先頭から最後までデータを確認するため、一見すると非効率な処理に見えることがあります。

例えば、100万件のユーザー情報が保存されているテーブルから特定のユーザーを1件だけ取得する場合、すべての行を確認するSeq Scanよりも、インデックスを利用して対象行を探すIndex Scanの方が高速になる場合があります。

しかし、Seq Scanは必ずしも悪い処理ではありません。PostgreSQLのオプティマイザは、テーブルサイズや取得件数、コスト計算の結果から、Seq Scanの方が効率的だと判断した場合にあえて選択します。

Seq Scanが発生する理由

PostgreSQLがSeq Scanを選択する主な理由の一つは、検索対象となるデータ量が多い場合です。

例えば、テーブルの80%の行を取得するようなSQLでは、インデックスを使って大量の行を探すよりも、テーブル全体を一度読み込んだ方が高速になることがあります。

インデックスを利用する場合、インデックスから対象行の場所を探した後、実際のテーブルデータを取得する処理が必要になります。そのため、取得件数が多い場合は逆にSeq Scanの方が効率的になります。

Seq Scanだけを理由にインデックスを追加してはいけない理由

Seq Scanが発生しているからといって、必ずSQLが遅いとは限りません。重要なのは、実際の処理時間や読み取っているデータ量です。

例えば、数千件程度の小さなテーブルでは、インデックスを利用するよりもSeq Scanの方が高速な場合があります。小規模なテーブルではインデックスを検索するコストの方が大きくなることもあります。

また、不要なインデックスを追加すると、検索性能が向上するどころか、INSERTやUPDATE、DELETEの処理速度低下につながる可能性があります。

インデックス追加前に確認すべき実行計画

PostgreSQLでSQLの改善を行う場合は、EXPLAINやEXPLAIN ANALYZEを利用して実際の実行計画を確認することが重要です。

EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'example@example.com';

実行計画では、Seq Scanが選択されている理由や、実際に読み取った行数、処理時間などを確認できます。

例えば、推定行数と実際の取得行数が大きく異なる場合は、統計情報が古くなっている可能性があります。その場合はインデックス追加ではなく、ANALYZEによる統計情報更新が有効なケースもあります。

インデックス追加を検討すべきケース

Seq Scanが問題になるケースは、少量のデータ取得にもかかわらず、大量のデータを読み込んでいる場合です。

例えば、数百万件の注文履歴テーブルから特定ユーザーの最新注文だけを取得する処理で、毎回Seq Scanが発生している場合は、検索条件に適したインデックスを検討する価値があります。

具体的には、WHERE句やJOIN条件、ORDER BYで頻繁に利用されるカラムに対してインデックスを作成することで、処理時間を短縮できる可能性があります。

インデックスを作成してもSeq Scanになる場合がある

インデックスを追加した後でも、PostgreSQLがSeq Scanを選択することがあります。これはインデックスが認識されていないのではなく、PostgreSQLがより効率的だと判断している可能性があります。

例えば、検索条件に一致する行がテーブル全体の半分以上存在する場合、インデックスを使うよりSeq Scanの方が高速になる場合があります。

また、WHERE句で関数を使用している場合や、データ型が一致していない場合などは、インデックスが利用されにくくなることもあります。

適切なパフォーマンス改善の進め方

PostgreSQLの性能改善では、まず遅いSQLを特定し、そのSQLの実行計画を確認することが基本です。

Seq Scanという文字だけを見るのではなく、処理時間、読み取り行数、テーブルサイズ、検索条件などを総合的に判断する必要があります。

例えば、日常的に大量のデータを取得する集計処理ではSeq Scanが適切な場合もあります。一方で、ユーザー検索や注文検索など少数取得が目的の処理ではインデックスが有効になることが多くあります。

まとめ:Seq Scanは悪ではなく、実行計画を見て判断することが重要

PostgreSQLでSeq Scanが発生していても、それだけでインデックス追加を決めるべきではありません。

Seq ScanはPostgreSQLのオプティマイザがコスト計算した結果、最適と判断して選択している場合があります。

性能改善を行う場合は、EXPLAIN ANALYZEで実際の処理状況を確認し、SQLの利用状況やデータ量を考慮した上で、本当にインデックスが必要か判断することが大切です。

コメント

タイトルとURLをコピーしました