I found that Postgres is not using an index for a range query on a partitioned table.
The parent table and its partitions have their date column indexed using btree.
A query like this:
select * from parent_table where date >= '2015-07-01';
does not use indexes.
EXPLAIN
result:
Append (cost=0.00..106557.52 rows=3263963 width=128)
-> Seq Scan on parent_table (cost=0.00..0.00 rows=1 width=640)
Filter: (date >= '2015-07-01'::date)
-> Seq Scan on z_partition_2015_07 (cost=0.00..106546.02 rows=3263922 width=128)
Filter: (date >= '2015-07-01'::date)
-> Seq Scan on z_partition_2015_08 (cost=0.00..11.50 rows=40 width=640)
Filter: (date >= '2015-07-01'::date)
But a query like this:
select * from parent_table where date = '2015-07-01'
uses an index.
EXPLAIN
result:
Append (cost=0.00..30400.95 rows=107602 width=128)
-> Seq Scan on parent_table (cost=0.00..0.00 rows=1 width=640)
Filter: (date = '2015-07-01'::date)
-> Index Scan using z_partition_2015_07_date on z_partition_2015_07 (cost=0.43..30400.95 rows=107601 width=128)
Index Cond: (date = '2015-07-01'::date)
When I run the query on a different normal table with date
indexed, both queries use the index.
Anything particular that we should do on partitioned table index?
VACUUM ANALYZE parent_table
to collect statistics on your partitioned table. If it didn't help try in psqlSET enable_seqscan = off
and repeat your query. Planner should use index scan so you could compare costs of seqscan and indexscan. Most likely seqscan is simply cheaper for this type of query. Indexscan is not very good at fetching large amounts of data.