Breaking it down, the problems here: - we repeatedly check privacy in all the subplans, ditto product.active Nested Loop (cost=3193.87..73534.16 rows=1303 width=280) - ok, not brilliant, but ok Nested Loop (cost=0.00..98481.42 rows=1499 width=280) - ditto Nested Loop Left Join (cost=0.00..49419.31 rows=711 width=280) - same And the problem child: -> Hash Join (cost=216449.03..292441.56 rows=190053 width=280) Hash Cond: (public.bugtask.bug = public.bug.id) -> Hash Left Join (cost=13260.49..88189.71 rows=251706 width=280) Hash Cond: (public.bugtask.product = public.product.id) Filter: ((public.bugtask.product IS NULL) OR public.product.active) -> Bitmap Heap Scan on bugtask (cost=10210.72..81759.72 rows=276144 width=280) Recheck Cond: ((status = 10) OR (status = 15) OR (status = 20) OR (status = 21) OR (status = 22) OR (status = 25)) -> BitmapOr (cost=10210.72..10210.72 rows=308640 width=0) -> Bitmap Index Scan on bugtask__status__idx (cost=0.00..5843.19 rows=184232 width=0) Index Cond: (status = 10) -> Bitmap Index Scan on bugtask__status__idx (cost=0.00..565.49 rows=17739 width=0) Index Cond: (status = 15) -> Bitmap Index Scan on bugtask__status__idx (cost=0.00..1792.13 rows=56490 width=0) Index Cond: (status = 20) -> Bitmap Index Scan on bugtask__status__idx (cost=0.00..959.11 rows=30221 width=0) Index Cond: (status = 21) -> Bitmap Index Scan on bugtask__status__idx (cost=0.00..169.28 rows=5311 width=0) Index Cond: (status = 22) -> Bitmap Index Scan on bugtask__status__idx (cost=0.00..467.30 rows=14647 width=0) Index Cond: (status = 25) -> Hash (cost=2776.19..2776.19 rows=21886 width=5) -> Seq Scan on product (cost=0.00..2776.19 rows=21886 width=5) Filter: active -> Hash (cost=202859.04..202859.04 rows=26360 width=8) -> Nested Loop (cost=35978.83..202859.04 rows=26360 width=8) -> HashAggregate (cost=35978.83..36016.24 rows=3741 width=4) -> Bitmap Heap Scan on bugmessage (cost=597.90..35912.93 rows=26360 width=4) Recheck Cond: ((owner = 100) AND (index > 0)) -> Bitmap Index Scan on bugmessage__owner__index__idx (cost=0.00..591.31 rows=26360 width=0) Index Cond: ((owner = 100) AND (index > 0)) -> Index Scan using bug_pkey on bug (cost=0.00..44.59 rows=1 width=4) Index Cond: (public.bug.id = bugmessage.bug) Filter: ((public.bug.duplicateof IS NULL) AND ((NOT public.bug.private) OR (SubPlan 1))) SubPlan 1 -> Unique (cost=39.33..39.34 rows=2 width=4) -> Sort (cost=39.33..39.33 rows=2 width=4) Sort Key: public.bugsubscription.bug -> Append (cost=0.00..39.32 rows=2 width=4) -> Nested Loop (cost=0.00..26.48 rows=1 width=4) -> Index Scan using bugsubscription_bug_idx on bugsubscription (cost=0.00..7.26 rows=3 width=8) Index Cond: (bug = $0) -> Index Scan using teamparticipation_team_key on teamparticipation (cost=0.00..6.39 rows=1 width=4) Index Cond: ((public.teamparticipation.team = public.bugsubscription.person) AND (public.teamparticipation.person = 2)) -> Nested Loop (cost=0.00..12.82 rows=1 width=4) -> Index Scan using bugtask__bug__idx on bugtask (cost=0.00..6.42 rows=1 width=8) Index Cond: (bug = $0) -> Index Scan using teamparticipation_team_key on teamparticipation (cost=0.00..6.39 rows=1 width=4) Index Cond: ((public.teamparticipation.team = public.bugtask.assignee) AND (public.teamparticipation.person = 2)) with an added seq scan on all bugs at the end -> Hash (cost=644777.55..644777.55 rows=712755 width=4) -> Seq Scan on bug (cost=0.00..644777.55 rows=712755 width=4) (estimated free because the planner expects to have already hit all bugs