I have the following table:
id message_read notification_sent send_date text version recipient sender
-- ------------ ----------------- ------------------- --------------------------------------------------- ------- --------- ------
1 true false 2015-02-27 00:00:00 Bonjour. Je suis disponible pour la garde partagée. 0 2 3
3 false false 2015-03-01 00:00:00 Je suis disponible pour vous rencontrer dès demain. 0 2 3
12 false false 2015-02-27 00:00:00 Hello dude 0 2 1
The query below is the type of queries that typically get run on this table:
select * from public.message
where (recipient = 2 and sender = 3) or (sender = 2 and recipient = 3);
I am trying to create efficient indices on this table and bearing in mind the kind of queries run on it.
Here are my indices:
CREATE INDEX recipient_idx ON message(recipient);
CREATE INDEX sender_idx ON message(sender);
and here is the output of a explain analyze on the query above:
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on message (cost=8.57..13.40 rows=1 width=49) (actual time=0.072..0.075 rows=3 loops=1)
Recheck Cond: ((sender = 3) OR (recipient = 3))
Filter: (((recipient = 2) AND (sender = 3)) OR ((sender = 2) AND (recipient = 3)))
Heap Blocks: exact=1
-> BitmapOr (cost=8.57..8.57 rows=2 width=0) (actual time=0.050..0.050 rows=0 loops=1)
-> Bitmap Index Scan on sender_idx (cost=0.00..4.28 rows=1 width=0) (actual time=0.037..0.037 rows=2 loops=1)
Index Cond: (sender = 3)
-> Bitmap Index Scan on recipient_idx (cost=0.00..4.28 rows=1 width=0) (actual time=0.009..0.009 rows=1 loops=1)
Index Cond: (recipient = 3)
Planning time: 0.468 ms
Execution time: 0.188 ms
Can anyone please tell me what I am getting wrong? Why isn't my query using a btree index and a bitmap one instead? How can I improve my indices?
edit:
Here is what I've tried:
CREATE INDEX recipient_sender_idx ON message(recipient, sender);
Running the explain analyze now yields:
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on message (cost=8.57..13.40 rows=1 width=49) (actual time=0.035..0.038 rows=3 loops=1)
Recheck Cond: ((sender = 3) OR (recipient = 3))
Filter: (((recipient = 2) AND (sender = 3)) OR ((sender = 2) AND (recipient = 3)))
Heap Blocks: exact=1
-> BitmapOr (cost=8.57..8.57 rows=2 width=0) (actual time=0.023..0.023 rows=0 loops=1)
-> Bitmap Index Scan on sender_idx (cost=0.00..4.28 rows=1 width=0) (actual time=0.015..0.015 rows=2 loops=1)
Index Cond: (sender = 3)
-> Bitmap Index Scan on recipient_idx (cost=0.00..4.28 rows=1 width=0) (actual time=0.007..0.007 rows=1 loops=1)
Index Cond: (recipient = 3)
Planning time: 0.183 ms
Execution time: 0.070 ms
edit 2:
explain analyze
select * from public.message
where recipient = 2 and sender = 3
UNION ALL
select * from public.message
where sender = 2 and recipient = 3
yields:
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------
Append (cost=0.29..16.63 rows=2 width=49) (actual time=0.031..0.043 rows=3 loops=1)
-> Index Scan using recipient_sender_idx on message (cost=0.29..8.31 rows=1 width=49) (actual time=0.030..0.031 rows=2 loops=1)
Index Cond: ((recipient = 2) AND (sender = 3))
-> Index Scan using recipient_sender_idx on message message_1 (cost=0.29..8.31 rows=1 width=49) (actual time=0.009..0.010 rows=1 loops=1)
Index Cond: ((recipient = 3) AND (sender = 2))
Planning time: 0.389 ms
Execution time: 0.075 ms
but it is not feasible to modify my SQL query.
ANALYZEd the table? How many rows do you have in the table and how many match this condition?