Schema:
Column | Type
----------------------+--------------------------
id | integer
event_id | integer
started_at | timestamp with time zone
ended_at | timestamp with time zone
created_at | timestamp with time zone
"event_seat_state_lookup_pkey" PRIMARY KEY, btree (id)
"event_seating_lookup_created_at_idx" btree (created_at)
"event_seating_lookup_created_at_idx2" gist (created_at)
Query:
SELECT id
FROM event_seating_lookup esl1
WHERE
tstzrange(now() - interval '1 hour', now() + interval '1 hour', '[)') @> esl1.created_at;
Explain analyze:
Table with <100k rows.
Seq Scan on event_seating_lookup esl1 (cost=0.00..1550.30 rows=148 width=4) (actual time=0.013..19.956 rows=29103 loops=1)
Filter: (tstzrange((now() - '01:00:00'::interval), (now() + '01:00:00'::interval), '[)'::text) @> created_at)
Buffers: shared hit=809
Planning Time: 0.110 ms
Execution Time: 21.942 ms
Table with 1M+ rows:
Seq Scan on event_seating_lookup esl1 (cost=10000000000.00..10000042152.75 rows=5832 width=4) (actual time=0.009..621.895 rows=1166413 loops=1)
Filter: (tstzrange((now() - '01:00:00'::interval), (now() + '01:00:00'::interval), '[)'::text) @> created_at)
Buffers: shared hit=12995
Planning Time: 0.092 ms
Execution Time: 697.927 ms
I have tried:
VACUUM FULL event_seating_lookup;
VACUUM event_seating_lookup;
VACUUM ANALYZE event_seating_lookup;
SET enable_seqscan = OFF;
Problem:
event_seating_lookup_created_at_idx
or event_seating_lookup_created_at_idx2
indexes are not being used.
Notes:
- PostgreSQL 11.1.
btree_gist
extension is installed.- I have tried equivalent setup with
created_at timestamp without time zone
and usingtsrange
; same result. - I understand that rewriting the query with
>=
,<
checks would make it use the btree index. The question is what is the reason the index is not used with thetstzrange
containment operator and if there is a way to make it work.