0

Я обнаружил, что Postgres не использует индекс для запроса диапазона в многораздельной таблице.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 индексируется, оба запроса использовать индекс.

Что-нибудь особенное, что мы должны сделать в индексе секционированных таблиц?

+0

попробуйте использовать дату между условием –

+0

Показать объяснение планов анализа для них обоих. –

+0

Трудно сказать, не зная о размере ваших данных и его структуре. Прежде всего попробуйте 'VACUUM ANALYZE parent_table' собрать статистику по вашей секционированной таблице. Если это не помогло в psql 'SET enable_seqscan = off' и повторить ваш запрос. Планировщик должен использовать индексное сканирование, чтобы сравнить стоимость seqscan и indexscan. Скорее всего seqscan просто дешевле для этого типа запросов.Indexscan не очень хорош в сборе больших объемов данных. –

ответ

0

Я предполагаю, что вы знаете, что «разделы» - это отдельные таблицы в Postgres. Индексы, как правило, не используется при извлечении больших частей таблицы (более чем на 5%, это зависит от многих деталей), потому что обычно быстрее сканировать таблицу последовательно в таких случаях.

Более того, кажется, что вы выбрали все строк из участвующих разделов в вашем первом запросе. Не допускается использование для индексов ...

Как правило, предикат равенства с = является более селективное чем предиката с >= .Think об этом:

Ваш первый запрос с date >= '2015-07-01' получающего все строки из раздела (угадывая, мне нужно будет увидеть точное определение). Использование индекса просто добавит накладные расходы. Но ваш второй запрос с date = '2015-07-01' получает только небольшой процент. Postgres ожидает, что сканирование индекса будет быстрее.

0

Возможно, это так быстро? выполните ваш запрос:

SET enable_seqscan=false 

И запустите его снова.

Смежные вопросы