Я обнаружил, что Postgres не использует индекс для запроса диапазона в многораздельной таблице.
Столбец даты родительской таблицы и ее разделов индексируется с помощью btree.
Такой запрос:
select * from parent_table where date >= '2015-07-01';
не использует индексы.
EXPLAIN
результат:
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)
Но такой запрос:
select * from parent_table where date = '2015-07-01'
использует индекс.
EXPLAIN
результат:
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)
Когда я запускаю запрос в другой нормальной таблице с индексом date
, оба запроса используют индекс.
Что-нибудь особенное, что мы должны сделать с индексом многораздельной таблицы?
VACUUM ANALYZE parent_table
собрать статистику по вашей многораздельной таблице. Если не помогло, попробуйте psqlSET enable_seqscan = off
и повторите свой запрос. Планировщику следует использовать сканирование индекса, чтобы вы могли сравнить затраты на сканирование seqscan и indexscan. Скорее всего, для этого типа запроса seqscan просто дешевле. Indexscan не очень хорош для получения больших объемов данных. - person Ildar Musin   schedule 06.04.2016SET enable_seqscan = off
, а затемexplain select * from parent_table where date >= '2015-07-01'
. Это стоит больше, чем seqscan? - person Ildar Musin   schedule 06.04.2016