Erwin, since this was our discussion in the comment thread from before, I decided to poke at it a little further...
I have a very simple query from a reasonably sized table. I typically have sufficient work_mem
, but in this case I used the commands
SET work_mem = 64;
to set a very small work_mem
and
SET work_mem = default;
to set my work_mem
back to being sufficiently large for my query.
EXPLAIN & Recheck Condition
So, running my query with only EXPLAIN
as
EXPLAIN
SELECT * FROM olap.reading_facts
WHERE meter < 20;
I obtained the results for both low & high work_mem
:
Low work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32)
Recheck Cond: (meter < 20)
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0)
Index Cond: (meter < 20)
High work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32)
Recheck Cond: (meter < 20)
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0)
Index Cond: (meter < 20)
Long story short, for EXPLAIN
only, as expected the query plan indicates that a Recheck condition is possible, but we can't know if will actually be computed.
EXPLAIN ANALYZE & Recheck Condition
When we include ANALYZE
in the query, the results tel us more about what we need to know.
Low work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32) (actual time=3.130..13.946 rows=51840 loops=1)
Recheck Cond: (meter < 20)
Rows Removed by Index Recheck: 86727
Heap Blocks: exact=598 lossy=836
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0) (actual time=3.066..3.066 rows=51840 loops=1)
Index Cond: (meter < 20)
High work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32) (actual time=2.647..7.247 rows=51840 loops=1)
Recheck Cond: (meter < 20)
Heap Blocks: exact=1434
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0) (actual time=2.496..2.496 rows=51840 loops=1)
Index Cond: (meter < 20)
Again, as expected, the inclusion of ANALYZE
reveals to us some very important information. In the low work_mem
case, we see that there are rows removed by the index recheck, and that we have lossy
heap blocks.
Conclusion? (or lack thereof)
Unfortunately, it looks like EXPLAIN
on its own is not sufficient to know whether an index recheck will actually be necessary because some of the row id's are being dropped in favor of retaining pages during the bitmap heap scan.
Using EXPLAIN ANALYZE
is fine for diagnosing the issues with moderate length queries, but in the case that a query is taking an extremely long time to complete, then running EXPLAIN ANALYZE
to discover that your bitmap index is converting to lossy due to insufficient work_mem
is still a difficult constraint. I wish there was a way to have EXPLAIN
estimate the likelihood of this occurrence from the table statistics.