I\'m running Postgres 9.5 and am playing around with BRIN indexes. I have a fact table with about 150 million rows and I\'m trying to get PG to use a BRIN index. My query
It seems like the BRIN index scan is not very selective – it returns 30 million rows, all of which have to be re-checked, which is where the time is spent.
That probably means that transaction_date_key
is not well correlated with the physical location of the rows in the table.
A BRIN index works by “lumping together” ranges of table blocks (how many can be configured with the storage parameter pages_per_range
, whose default value is 128). The maximum and minimum of the indexed value for eatch range of blocks is stored.
So a lot of block ranges in your table contain transaction_date_key
between 20170101
and 20170201
, and all of these blocks have to be scanned to compute the query result.
I see two options to improve the situation:
Lower the pages_per_range
storage parameter. That will make the index bigger, but it will reduce the number of “false positive” blocks.
Cluster the table on the transaction_date_key
attribute. As you have found out, that requires (at least temporarily) a B-tree index on the column.