PostgreSQLでは、インデックスのメンテナンスやチューニングは必要ありませんが、どのインデックスが実際の問い合わせで使われているかを確認することは、やはり重要です。 個々のコマンドでのインデックスの使用状況は、EXPLAINコマンドで検証できます。 この目的のための用例を14.1に示します。 また、28.2に示す通り、稼働中のサーバにおけるインデックス使用状況の全体的な統計情報を取り出すこともできます。
どのインデックスを作成すべきかを判断するための一般的な手順を定めることは困難です。 これまでの節では、例として典型的なケースをいくつか記述してきました。 十分な検証がしばしば必要です。 本節の残りで、検証のためのヒントをいくつか説明しておきます。
まず、必ずANALYZEコマンドを実行してください。
このコマンドにより、テーブル内の値の分布に関する統計情報を収集します。
この情報は、問い合わせにより返される行数を推測する際に必要となります。
推測された行数は、可能な各問い合わせ計画に実際のコストを割り当てるために、プランナで必要となります。
実際の統計情報が欠如している場合、何らかのデフォルト値が仮定されますが、このデフォルト値は、ほぼ間違いなく不正確です。
したがって、ANALYZE
コマンドを実行せずに、アプリケーションのインデックス使用状況を検証しても、あまり意味がありません。
より詳細な情報は25.1.3と25.1.6を参照してください。
検証には、実際に使用するデータを使ってください。 テストデータを使ってインデックスを作成した場合、テストデータに必要なインデックスはわかりますが、それ以上はわかりません。
非常に小さなテストデータを使用することも、結果に特に致命的な影響を与えます。 100,000行から1,000行を選択する場合は、インデックスが使用される可能性がありますが、100行から1行を選択する場合はインデックスはまず使用されません。 なぜなら、100行はおそらく1つのディスクページに収まるため、1ページを逐次読み取るよりも高速な計画は存在しないからです。
また、アプリケーションがまだ実動していない場合、テストデータを作成しなければならないことがよくありますが、その際にも注意が必要です。 非常に類似した値や、完全にランダムな値、またはソートされた順序で値が挿入されている場合は、その統計情報は、実際のデータの分布とかけ離れたものになってしまいます。
インデックスが使用されていない場合、テストのためにインデックスを強制的に使用するようにすると便利です。
様々な計画の種類を無効にすることを設定できる実行時パラメータがあります
(20.7.1を参照してください)。
例えば、最も基本的な計画であるシーケンシャルスキャン(enable_seqscan
)およびネステッドループ結合(enable_nestloop
)を無効に設定すると、システムは別の計画を使用するように強制されます。
そのような設定を行っても、システムがシーケンシャルスキャンやネステッドループ結合を選択する場合は、インデックスを使用しない理由としておそらくもっと根本的な理由があるということになります。
例えば、問い合わせの条件がインデックスに適合しない、などが考えられます。
(どのような問い合わせで、どのようなインデックスを使用できるかは、前節までで説明済みです。)
強制的にインデックスを使うように設定することで、インデックスを使用するようになった場合は、次の2つの可能性が考えられます。
システムの判断が正しく、インデックスの使用が実際には適切ではないという可能性と、問い合わせ計画のコスト推定が実情を反映していない可能性です。
したがって、インデックスを使った問い合わせの実行時間と、使わない場合の実行時間を計測する必要があります。
この場合、EXPLAIN ANALYZE
コマンドが便利です。
コスト推定が間違っていると判明した場合、やはり2つの可能性が考えられます。 総コストは、各計画ノードの行単位のコストに、計画ノードの推定選択度を掛けることで算出されます。 計画ノードのコスト推定は、実行時パラメータによって設定することができます (20.7.2を参照してください)。 推定選択度が不正確であるのは、統計情報が不十分であるのが原因です。 統計情報収集用のパラメータを調節することによって、この状況を改善することができるかもしれません。 (ALTER TABLEを参照してください)。
コストを適切に調節できない場合は、明示的にインデックスの使用を強制する必要が考えられます。 あるいは、PostgreSQL開発者に問題の調査を依頼することになるかもしれません。