2017-06-08 3 views
0

私は非常に奇妙なpostgresクエリの動作に直面しています。私は別のテーブルのパーティションであるテーブル "p_MyTable"を持っています。 「p_MyTable」は約600万レコードを持っており、インデックスを持っている私は、以下のクエリを実行すると、Postgresクエリでインデックスを使用していません

CREATE INDEX idx_p_MyTable_id ON MySchema.p_MyTable USING btree(IndColumn); 

は、それは時間がないで実行され、非常に高速な結果を与えます。これはクエリと説明の計画です。

explain select max(IndColumn) from MySchema.p_MyTable ms where ent_attr_97='ABC' and ent_attr_96='EFG' and ent_attr_98='HIJ' 
and ent_date_2::date <= '2017-06-01 00:00:00'::date 

"Result (cost=4.85..4.86 rows=1 width=0)" 
" InitPlan 1 (returns $0)" 
" -> Limit (cost=0.57..4.85 rows=1 width=8)" 
"   -> Index Scan Backward using idx_p_MyTable_id on p_MyTable ms (cost=0.57..727648341.49 rows=169996075 width=8)" 
"    Index Cond: (IndColumn IS NOT NULL)" 
"    Filter: ((ent_attr_97 = 'ABC'::text) AND (ent_attr_96 = 'EFG'::text) AND (ent_attr_98 = 'HIJ'::text) AND ((ent_date_2)::date <= '2017-06-01'::date))" 

これは、同じように集計関数 "min"で機能します。しかし、私が他の機能を試してみると、説明プランは変わり、クエリは数分で実行されません。

explain select count(IndColumn) from MySchema.p_MyTable ms where ent_attr_97='ABC' and ent_attr_96='EFG' and ent_attr_98='HIJ' 
and ent_date_2::date <= '2017-06-01 00:00:00'::date 

"Aggregate (cost=53319339.50..53319339.51 rows=1 width=8)" 
" -> Bitmap Heap Scan on p_MyTable ms (cost=11209851.27..52894349.31 rows=169996075 width=8)" 
"  Recheck Cond: (ent_attr_96 = 'EFG'::text)" 
"  Filter: ((ent_attr_97 = 'ABC'::text) AND (ent_attr_98 = 'HIJ'::text) AND ((ent_date_2)::date <= '2017-06-01'::date))" 
"  -> Bitmap Index Scan on p_MyTable_comp (cost=0.00..11167352.25 rows=509988224 width=0)" 
"    Index Cond: (ent_attr_96 = 'EFG'::text)" 

explain select distinct (IndColumn) from MySchema.p_MyTable ms where ent_attr_97='ABC' and ent_attr_96='EFG' and ent_attr_98='HIJ' 
and ent_date_2::date <= '2017-06-01 00:00:00'::date 

"HashAggregate (cost=53319339.50..53319339.71 rows=21 width=8)" 
" Group Key: IndColumn" 
" -> Bitmap Heap Scan on p_MyTable ms (cost=11209851.27..52894349.31 rows=169996075 width=8)" 
"  Recheck Cond: (ent_attr_96 = 'EFG'::text)" 
"  Filter: ((ent_attr_97 = 'ABC'::text) AND (ent_attr_98 = 'HIJ'::text) AND ((ent_date_2)::date <= '2017-06-01'::date))" 
"  -> Bitmap Index Scan on p_MyTable_comp (cost=0.00..11167352.25 rows=509988224 width=0)" 
"    Index Cond: (ent_attr_96 = 'EFG'::text)" 

explain select avg (IndColumn) from MySchema.p_MyTable ms where ent_attr_97='ABC' and ent_attr_96='EFG' and ent_attr_98='HIJ' 
and ent_date_2::date <= '2017-06-01 00:00:00'::date 

"Aggregate (cost=53319339.50..53319339.51 rows=1 width=8)" 
" -> Bitmap Heap Scan on p_MyTable ms (cost=11209851.27..52894349.31 rows=169996075 width=8)" 
"  Recheck Cond: (ent_attr_96 = 'EFG'::text)" 
"  Filter: ((ent_attr_97 = 'ABC'::text) AND (ent_attr_98 = 'HIJ'::text) AND ((ent_date_2)::date <= '2017-06-01'::date))" 
"  -> Bitmap Index Scan on p_MyTable_comp (cost=0.00..11167352.25 rows=509988224 width=0)" 
"    Index Cond: (ent_attr_96 = 'EFG'::text)" 

私は適切にインデックスを使用している最大/最小ならば、それは、他の機能のために働くべきだと思うように完全な変更を説明し、なぜ、私を説明してください。

ありがとうございます。

+0

私は、テーブルが真空引きされ、最近分析されたことを確認しました。 – sand

答えて

0

索引は、「場所」条件のいずれか、またはソート(「注文者」)に役立ちます(ほとんど)。クエリは次のように書き換えられているため (ウェルインデックスは他のものの多くのために使用することができるが、この場合のために、それはこれらの例に制限するのに役立ちます)

「最大(IndColumn)」、紛らわしいです:

select IndColumn 
from MySchema.p_MyTable ms 
where ent_attr_97='ABC' and ent_attr_96='EFG' and ent_attr_98='HIJ' 
and ent_date_2::date <= '2017-06-01 00:00:00'::date 
AND IndColumn is not null 
ORDER by IndColumn desc 
LIMIT 1 

したがって、「AND IndColumnは、IndColumn descによるnull ORDERではありません」の索引が使用されます。

あなたが

CREATE INDEX idx_p_foo ON MySchema.p_MyTable USING btree(ent_attr_96, ent_attr_97, ent_attr_98); 

よう 何かが役立つかもしれない、「」内の列のインデックスが必要になり、あなたの他のクエリのために

。 これらの3つの列を使用する多数のクエリがあるとします。

また、日付を追加することもできます。私はこれが多くの助けになるとは確信していませんが、それは終了日であり、開始が与えられていないからです。 クエリプレーナがインデックス内の日付を使用するかどうかはわかりません。そして、そうするならば、問題は、日付によってフィルタリングされる行の数です。インデックスのサイズを増やす価値はありますか?

関連する問題