I have a PostgreSQL query that is taking longer than I'd like. I'm looking at the output of EXPLAIN ANALYZE
and it mentions a Bitmap Index Scan
. I've been searching the 'net and reading for about 10 minutes, but I cannot figure out:
Is a Bitmap Index a manufactured thing—something that I could improve if I added a real index to some column somewhere—or is it a specific type of a real index?
Here's the single table that I'm querying:
bugbot4b=> \d bug_snapshots
Table "public.bug_snapshots"
Column | Type | Modifiers
------------+-----------------------------+-----------
fixin_id | integer | not null
created_on | timestamp without time zone | not null
pain | integer | not null
status_id | integer | not null
Indexes:
"bug_snapshots_pkey" PRIMARY KEY, btree (fixin_id, created_on)
Foreign-key constraints:
"bug_snapshots_fixin_id_fkey" FOREIGN KEY (fixin_id) REFERENCES fixins(id) ON DELETE SET NULL
"bug_snapshots_status_id_fkey" FOREIGN KEY (status_id) REFERENCES statuses(id)
And here's the result of analyzing the query. Note that there are about 3k distinct fixin_id
literally within the query (elided in the below), and the table has 900k rows. Counting just those rows within the particular time range yields 15,000 rows.
EXPLAIN ANALYZE SELECT "created_on", sum("pain") AS "sum_pain" FROM "bug_snapshots"
WHERE (("fixin_id" IN (11,12,33,…,5351))
AND ("status_id" IN (2, 7, 5, 3))
AND ("created_on" >= '2013-10-08 16:42:26.994994-0700')
AND ("created_on" <= '2013-11-07 15:42:26.994994-0800')
AND ("pain" < 999))
GROUP BY "created_on"
ORDER BY "created_on";
Sort (cost=59559.33..59559.38 rows=20 width=12) (actual time=19.472..19.494 rows=30 loops=1)
Sort Key: created_on
Sort Method: quicksort Memory: 18kB
-> HashAggregate (cost=59558.64..59558.89 rows=20 width=12) (actual time=19.401..19.428 rows=30 loops=1)
-> Bitmap Heap Scan on bug_snapshots (cost=9622.42..59509.25 rows=9878 width=12) (actual time=6.849..13.420 rows=6196 loops=1)
Recheck Cond: ((fixin_id = ANY ('{11,12,33,…,5351}'::integer[])) AND (created_on >= '2013-10-08 16:42:26.994994'::timestamp without time zone) AND (created_on <= '2013-11-07 15:42:26.994994'::timestamp without time zone))
Filter: ((pain < 999) AND (status_id = ANY ('{2,7,5,3}'::integer[])))
-> Bitmap Index Scan on bug_snapshots_pkey (cost=0.00..9619.95 rows=11172 width=0) (actual time=6.801..6.801 rows=6196 loops=1)
Index Cond: ((fixin_id = ANY ('{11,12,33,…,5351}'::integer[])) AND (created_on >= '2013-10-08 16:42:26.994994'::timestamp without time zone) AND (created_on <= '2013-11-07 15:42:26.994994'::timestamp without time zone))
Total runtime: 19.646 ms
(10 rows)
Is the result of ANALYZE telling me that I need to add an index to the fixin_id (and/or other fields) to improve the speed? Or that this is just "slow" because of its size?