2017-02-07 27 views
4

Я запускаю Postgres 9.5 и играю с индексами BRIN. У меня есть таблица фактов с примерно 150 миллионами строк, и я пытаюсь заставить PG использовать индекс BRIN. Мой запрос:Postgres, выбрав BTREE вместо индекса BRIN

select sum(transaction_amt), 
     sum (total_amt) 
from fact_transaction 
where transaction_date_key between 20170101 and 20170201 

Я создал как индекс ВТКЕЯ и индекс Брин (по умолчанию значения pages_per_range 128) на колонок transaction_date_key (выше запрос со ссылкой на январь-февраль 2017 г.). Я бы подумал, что PG предпочтет использовать индекс BRIN, однако он идет с индексом BTREE. Вот план объяснить:

https://explain.depesz.com/s/uPI

Затем я удалил индекс ВТКЕЯ, сделал вакуум/анализ на столе, и снова запускал запрос и сделали выбрать индекс Брин однако пробег время значительно продолжительнее:

https://explain.depesz.com/s/5VXi

на самом деле мои тесты были быстрее при использовании индекса ВТКЕЯ, а не индекс Брин. Я думал, что это должно быть наоборот?

Я бы предпочел использовать индекс BRIN из-за его меньшего размера, однако я не могу заставить PG использовать его.

Примечание. Я загрузил данные, начиная с января 2017 года по июнь 2017 года (определяется с помощью transaction_date_key), когда я читал, что упорядочение физических таблиц имеет значение при использовании индексов BRIN.

Кто-нибудь знает, почему PG предпочитает использовать индекс BTREE и почему BRIN настолько медленнее в моем случае?

+0

Можете ли вы показать нам выход 'объяснить (анализирующих, многословным, буферы, сроки)' вместо «просто» 'объяснить (анализировать)' –

+0

Конечно - запуская их в настоящее время. – Ryan

+0

B-Tree и BRIN: https://explain.depesz.com/s/S3Zp BRIN только: https://explain.depesz.com/s/Z1A5 – Ryan

ответ

3

Похоже, что сканирование индекса BRIN не очень избирательно. – возвращает 30 миллионов строк, все из которых должны быть перепроверены, и в этом случае время тратится.

Это, вероятно, означает, что transaction_date_key плохо коррелирует с физическим расположением строк в таблице.

BRIN index works “ от комков вместе ” диапазонов таблицы блоков (сколько может быть сконфигурирован с параметром хранения pages_per_range, чье значение по умолчанию 128). Сохраняется максимальное и минимальное значение индексированного значения для диапазона блоков приема.

Так много диапазонов блоков в таблице содержит transaction_date_key между 20170101 и 20170201, и всеми этими блоками должны быть отсканированы для вычисления результата запроса.

Я вижу два варианта, чтобы улучшить ситуацию:

  • Опустите параметр pages_per_range хранения. Это сделает индекс больше, но это уменьшит количество “ ложных положительных ” блоков.

  • Кластер стол по атрибуту transaction_date_key. Как вы выяснили, для этого требуется (по крайней мере временно) индекс B-дерева в столбце.