INDEXがあるのに遅い
「インデックス貼ってるのに遅い...」
そんな経験ありませんか?
実はPostgreSQLでは、特定の書き方やデータ状況によって
INDEXがまったく使われないケースがあります。
この記事では、実務でハマりやすい原因をまとめました。
INDEXが効かない原因
PostgreSQLでINDEXが効かない原因として、大きく以下があります。
①SQLの書き方でINDEXが効かない(最も多い原因)
②データが想定外
③INDEXが断片化している
①単体テストで確認すべきですが、確認していないプロジェクトも多いと思います。
単体テストで確認しないと、遅く感じた時にしか気付かない。
INDEXの項目に対し、以下を使用すると基本的にINDEXは使われません。
1.関数を使う
例:WHERE TO_CHAR(日付項目, 'YYYYMMDD') = '20260401'
↓ このようにINDEXの項目に関数を使うと、INDEXは使われません。
この場合は以下のように記述します。
WHERE 日付項目 = TO_DATE('20260401', 'YYYYMMDD')
2.前半一致以外の部分一致、つまり 中間一致や後方一致
3.演算を使う
4.暗黙の型変換
例:WHERE 品番 = 123456
↓ 文字型の品番が数値だった場合、この記述だと型変換が行われ、
INDEXが使われなくなるため、以下のように記述する。
WHERE 品番 = '123456'
5.否定形を使う
6.OR条件はケースによってINDEXが使われにくくなる
7.NULL検索はINDEXが使われないケースがある
②の詳細
INDEXは取得するデータの割合が少ない時に使われる。
・テスト環境の場合
・本番環境と異なり、データが想定と異なっている
・本番環境の場合
・データの偏りが変わり、統計情報が古く、データと統計情報がアンマッチ
※統計情報はANALYZEで更新可能
EXPLAINで実行計画を確認すると気付きやすい。
③の詳細
私の経験上、殆どのプロジェクトでINDEXを再構築していないため、
INDEXの断片化や肥大化により、パフォーマンスに影響する場合がある。
INDEXはデータをINSERTするだけでも断片化し、サイズが大きくなる。
※再構築することで改善が見込まれます。
以下の場合、断片化しやすい。
・データを削除している
・INDEXの項目に対し、昇順にINSERTされにくい(例:売上データの商品コードなど)
以下の場合、テーブルスキャンが選択されやすくなる。
・INDEXの項目が多い
・テーブルのレコード長が短い
・INDEXの項目のカーディナリティ(値の数 [バリエーション])が低い
まとめ 【チェックリスト】
■INDEXが効かない時は 以下を確認しましょう。
・関数を項目側に使っていないか?
・型変換が発生していないか?
・LIKEが前方一致になっているか?
・OR条件になっていないか?
・統計情報が最新か?
関連記事
- データベース(PostgreSQL)のINDEX再構築の目安
- PostgreSQLでシステムテスト以降で性能を改善する監視すべきポイント その2
- PostgreSQLのインデックス再構築運用(断片化監視と実務での対応)
補足(より深く学びたい方へ)
今回のような「性能問題の原因分析」やチューニングの具体的な
手順について、講座で体系的に解説しています。
※現在Udemyセール中のため、通常より安く受講できます。
残り 1日です。
URL:https://www.udemy.com/course/postgresql-sql/?referralCode=64B372729B6BC0073ACB