Although indexes in <productname>PostgreSQL</productname> do not need maintenance or tuning, it is still important to check which indexes are actually used by the real-life query workload. Examining index usage for an individual query is done with the <xref linkend="sql-explain"/> command; its application for this purpose is illustrated in <xref linkend="using-explain"/>. It is also possible to gather overall statistics about index usage in a running server, as described in <xref linkend="monitoring-stats"/>. PostgreSQLでは、インデックスのメンテナンスやチューニングは必要ありませんが、どのインデックスが実際の問い合わせで使われているかを確認することは、やはり重要です。 個々のコマンドでのインデックスの使用状況は、EXPLAINコマンドで検証できます。 この目的のための用例を14.1に示します。 また、27.2に示す通り、稼働中のサーバにおけるインデックス使用状況の全体的な統計情報を取り出すこともできます。
It is difficult to formulate a general procedure for determining which indexes to create. There are a number of typical cases that have been shown in the examples throughout the previous sections. A good deal of experimentation is often necessary. The rest of this section gives some tips for that: どのインデックスを作成すべきかを判断するための一般的な手順を定めることは困難です。 これまでの節では、例として典型的なケースをいくつか記述してきました。 十分な検証がしばしば必要です。 本節の残りで、検証のためのヒントをいくつか説明しておきます。
Always run <xref linkend="sql-analyze"/>
first. This command
collects statistics about the distribution of the values in the
table. This information is required to estimate the number of rows
returned by a query, which is needed by the planner to assign
realistic costs to each possible query plan. In absence of any
real statistics, some default values are assumed, which are
almost certain to be inaccurate. Examining an application's
index usage without having run <command>ANALYZE</command> is
therefore a lost cause.
See <xref linkend="vacuum-for-statistics"/>
and <xref linkend="autovacuum"/> for more information.
まず、必ずANALYZEコマンドを実行してください。
このコマンドにより、テーブル内の値の分布に関する統計情報を収集します。
この情報は、問い合わせにより返される行数を推測する際に必要となります。
推測された行数は、可能な各問い合わせ計画に実際のコストを割り当てるために、プランナで必要となります。
実際の統計情報が欠如している場合、何らかのデフォルト値が仮定されますが、このデフォルト値は、ほぼ間違いなく不正確です。
したがって、ANALYZE
コマンドを実行せずに、アプリケーションのインデックス使用状況を検証しても、あまり意味がありません。
より詳細な情報は24.1.3と24.1.6を参照してください。
Use real data for experimentation. Using test data for setting up indexes will tell you what indexes you need for the test data, but that is all. 検証には、実際に使用するデータを使ってください。 テストデータを使ってインデックスを作成した場合、テストデータに必要なインデックスはわかりますが、それ以上はわかりません。
It is especially fatal to use very small test data sets. While selecting 1000 out of 100000 rows could be a candidate for an index, selecting 1 out of 100 rows will hardly be, because the 100 rows probably fit within a single disk page, and there is no plan that can beat sequentially fetching 1 disk page. 非常に小さなテストデータを使用することも、結果に特に致命的な影響を与えます。 100,000行から1,000行を選択する場合は、インデックスが使用される可能性がありますが、100行から1行を選択する場合はインデックスはまず使用されません。 なぜなら、100行はおそらく1つのディスクページに収まるため、1ページを逐次読み取るよりも高速な計画は存在しないからです。
Also be careful when making up test data, which is often unavoidable when the application is not yet in production. Values that are very similar, completely random, or inserted in sorted order will skew the statistics away from the distribution that real data would have. また、アプリケーションがまだ実動していない場合、テストデータを作成しなければならないことがよくありますが、その際にも注意が必要です。 非常に類似した値や、完全にランダムな値、またはソートされた順序で値が挿入されている場合は、その統計情報は、実際のデータの分布とかけ離れたものになってしまいます。
When indexes are not used, it can be useful for testing to force
their use. There are run-time parameters that can turn off
various plan types (see <xref linkend="runtime-config-query-enable"/>).
For instance, turning off sequential scans
(<varname>enable_seqscan</varname>) and nested-loop joins
(<varname>enable_nestloop</varname>), which are the most basic plans,
will force the system to use a different plan. If the system
still chooses a sequential scan or nested-loop join then there is
probably a more fundamental reason why the index is not being
used; for example, the query condition does not match the index.
(What kind of query can use what kind of index is explained in
the previous sections.)
インデックスが使用されていない場合、テストのためにインデックスを強制的に使用するようにすると便利です。
様々な計画の種類を無効にすることを設定できる実行時パラメータがあります
(19.7.1を参照してください)。
例えば、最も基本的な計画であるシーケンシャルスキャン(enable_seqscan
)およびネステッドループ結合(enable_nestloop
)を無効に設定すると、システムは別の計画を使用するように強制されます。
そのような設定を行っても、システムがシーケンシャルスキャンやネステッドループ結合を選択する場合は、インデックスを使用しない理由としておそらくもっと根本的な理由があるということになります。
例えば、問い合わせの条件がインデックスに適合しない、などが考えられます。
(どのような問い合わせで、どのようなインデックスを使用できるかは、前節までで説明済みです。)
If forcing index usage does use the index, then there are two
possibilities: Either the system is right and using the index is
indeed not appropriate, or the cost estimates of the query plans
are not reflecting reality. So you should time your query with
and without indexes. The <command>EXPLAIN ANALYZE</command>
command can be useful here.
強制的にインデックスを使うように設定することで、インデックスを使用するようになった場合は、次の2つの可能性が考えられます。
システムの判断が正しく、インデックスの使用が実際には適切ではないという可能性と、問い合わせ計画のコスト推定が実情を反映していない可能性です。
したがって、インデックスを使った問い合わせの実行時間と、使わない場合の実行時間を計測する必要があります。
この場合、EXPLAIN ANALYZE
コマンドが便利です。
If it turns out that the cost estimates are wrong, there are, again, two possibilities. The total cost is computed from the per-row costs of each plan node times the selectivity estimate of the plan node. The costs estimated for the plan nodes can be adjusted via run-time parameters (described in <xref linkend="runtime-config-query-constants"/>). An inaccurate selectivity estimate is due to insufficient statistics. It might be possible to improve this by tuning the statistics-gathering parameters (see <xref linkend="sql-altertable"/>). コスト推定が間違っていると判明した場合、やはり2つの可能性が考えられます。 総コストは、各計画ノードの行単位のコストに、計画ノードの推定選択度を掛けることで算出されます。 計画ノードのコスト推定は、実行時パラメータによって設定することができます (19.7.2を参照してください)。 推定選択度が不正確であるのは、統計情報が不十分であるのが原因です。 統計情報収集用のパラメータを調節することによって、この状況を改善することができるかもしれません。 (ALTER TABLEを参照してください)。
If you do not succeed in adjusting the costs to be more appropriate, then you might have to resort to forcing index usage explicitly. You might also want to contact the <productname>PostgreSQL</productname> developers to examine the issue. コストを適切に調節できない場合は、明示的にインデックスの使用を強制する必要が考えられます。 あるいは、PostgreSQL開発者に問題の調査を依頼することになるかもしれません。