146

Postgres がインデックスを使用するよう強制するにはどうすればよいですか?

4

9 に答える 9

124

多くのデータベースに見られる一般的な「インデックスヒント」機能について質問していると仮定すると、PostgreSQLはそのような機能を提供しません。これは、PostgreSQLチームによって行われた意識的な決定でした。代わりに何ができるのか、その理由の概要については、こちらをご覧ください。その理由は基本的に、データが変更されると後でさらに問題を引き起こす傾向があるパフォーマンスハックであるのに対し、PostgreSQLのオプティマイザは統計に基づいて計画を再評価できるためです。言い換えると、今日の適切なクエリプランは、常に適切なクエリプランではない可能性があり、インデックスヒントは、特定のクエリプランを常に強制します。

テストに役立つ非常に鈍いハンマーとして、enable_seqscanおよびenable_indexscanパラメーターを使用できます。見る:

これらは、継続的な本番環境での使用には適していません。クエリプランの選択に問題がある場合は、クエリパフォーマンスの問題を追跡するためのドキュメントを参照してください。enable_パラメータを設定して立ち去るだけではいけません。

インデックスを使用する非常に正当な理由がない限り、Postgresが正しい選択をしている可能性があります。なんで?

  • 小さなテーブルの場合、順次スキャンを実行する方が高速です。
  • データ型が適切に一致しない場合、Postgresはインデックスを使用しません。適切なキャストを含める必要がある場合があります。
  • プランナーの設定が問題を引き起こしている可能性があります。

この古いニュースグループの投稿も参照してください。

于 2008-11-21T19:04:03.803 に答える
97

おそらく使用する唯一の正当な理由

set enable_seqscan=false

クエリを作成していて、テーブルに大量のデータがあった場合にクエリ プランが実際にどうなるかをすばやく確認したい場合です。またはもちろん、データセットが小さすぎるという理由だけでクエリがインデックスを使用していないことをすばやく確認する必要がある場合。

于 2012-11-16T01:33:06.460 に答える
25

PostgreSQL が特定の条件に最適なインデックスを選択できないことがあります。例として、数百万行のトランザクション テーブルがあり、そのうちの 1 日には数百行あり、テーブルには 4 つのインデックス (transaction_id、client_id、date、description) があるとします。次のクエリを実行します。

SELECT client_id, SUM(amount)
FROM transactions
WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND
      description = 'Refund'
GROUP BY client_id

PostgreSQL は、transactions_date_idx ではなく、transactions_description_idx インデックスを使用することを選択する場合があります。これにより、クエリに 1 秒未満ではなく、数分かかる場合があります。この場合、次のように条件をごまかすことで、日付のインデックスを強制的に使用できます。

SELECT client_id, SUM(amount)
FROM transactions
WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND
      description||'' = 'Refund'
GROUP BY client_id
于 2015-06-16T05:17:16.040 に答える
11

質問自体は非常に無効です。強制する (たとえば enable_seqscan=off を実行する) ことは非常に悪い考えです。より高速になるかどうかを確認することは役立つかもしれませんが、製品コードではそのようなトリックを使用しないでください。

代わりに、クエリの分析を説明し、それを読んで、PostgreSQL が悪い (あなたの意見では) 計画を選択する理由を調べてください。

Explain Analyzeの出力を読むのに役立つツールがウェブ上にあります。そのうちの 1 つがExplain.depesz.comです。

もう 1 つのオプションは、 freenode irc ネットワークの#postgresql チャネルに参加し、そこにいる人たちと話をして助けてもらうことです。それは会話のようなもので、確認すべきことがたくさんあり、学ぶべきことがたくさんあります。

于 2009-07-09T17:58:04.820 に答える