2016-05-06 1 views
0

私はこの種のインデックスを持っている:postgresqlは、データがwhere句にある場合にpostgresqlがそのインデックスを使用するとき、そのインデックスを避ける原因は何ですか?

id, start_time, end_time 

は、私はそれから取得するために必要な情報を持つ非常に大きなテーブルがあります。私はセカンダリテーブルを持っています:

id, min_time, max_time 

これは基本的に私は大きなテーブルから取得する必要が時間範囲に対応します。どちらの場合もIDは一致します。

私は2つのテーブルを使って結合すると、postgresqlはテーブルスキャンを実行し、次にネストされたループで小さなテーブルと結合することをお勧めします。たとえば、小さなテーブルに3つのレコードがある場合、索引を使用して3つのIDにフィルタリングするのではなく、困難な方法で処理します。

私は実際にはクエリの前にPythonで小さなテーブルを作成していますので、代わりにwhere句の条件を厳密にコーディングするか、最低限、where句にIDを入れて結合します。私がこれを行う場合、実際には期待どおりインデックスを使用します。

私の質問は、なぜこのケースで明らかにできる場合、Postgresは結合のインデックスを利用しないのですか?これは分析を実行する必要があるケースではありませんが、それは役に立ちません。パフォーマンスの差は大きさです。小さなテーブルから始め、その後大きなテーブルに参加する必要がありますが、最初に小さいテーブルから選択してもそれを行うことはできません。

EDIT提出する前に:

を私は小さなテーブル定義は、列定義にNOT NULL欠けていた、それを考え出しました。これを追加すると、期待どおりに動作します。

これは、この非常にイライラした問題を遭遇する可能性のある他の人のためにここに残しておきます。

+2

編集で回答しないでください。答えを「実際の」回答に移動し、それを受け入れます。 –

答えて

0

私はそれを理解しましたが、小さいテーブル定義では列定義にNOT NULLがありませんでした。これを追加すると、期待どおりに動作します。オプティマイザtbhのバグのようです。すべての列が許可されたNULLで結合されています。

0

Postgresのクエリプランニングは非常に優れています(データベース統計が古すぎないと仮定して)。おそらく、Postgresは、インデックスを使用するのではなく、小さなテーブル全体をスキャンするほうが効率的であるという決定を下しました。小さなテーブルの場合は、ブルートフォースがしばしば優れています。

+0

これはそうではありませんでした。 postgresqlは、null/not nullの制限に基づいて使用していたはずのインデックスを避けていたようです。数百万行のテーブルをテーブルスキャンするのは効率的ではありません。 – JamesHutchison

関連する問題