temp table: select bugtask.*, duplicateof, latest_patch_uploaded, private into temporary table bugtask2 from bug,bugtask where bug.id=bugtask.bug; and a query on it: (bugtask2 as bugtask, assignee check dropped for the experiment: we can look at making a special sort of subscription or something). SELECT BugTask.status, BugTask.importance, Bugtask.latest_patch_uploaded IS NOT NULL, (EXISTS (SELECT TRUE FROM BugTask AS RelatedBugTask WHERE RelatedBugTask.bug = BugTask.bug AND RelatedBugTask.id != BugTask.id AND ((RelatedBugTask.bugwatch IS NOT NULL AND RelatedBugTask.status IN (17, 25, 30)) OR (RelatedBugTask.product IS NOT NULL AND RelatedBugTask.bugwatch IS NULL AND RelatedBugTask.status IN (25, 30))))), COUNT(DISTINCT BugTask.bug) FROM BugTask2 as bugtask WHERE BugTask.distribution = 1 AND ((BugTask.status = 10) OR (BugTask.status = 15) OR (BugTask.status = 20) OR (BugTask.status = 21) OR (BugTask.status = 22) OR (BugTask.status = 25)) AND Bugtask.duplicateof IS NULL AND (Bugtask.private = FALSE OR EXISTS (SELECT BugSubscription.bug FROM BugSubscription, TeamParticipation WHERE TeamParticipation.person = 3199329 AND TeamParticipation.team = BugSubscription.person AND BugSubscription.bug = bugtask.bug) ) GROUP BY BugTask.status, BugTask.importance, Bugtask.latest_patch_uploaded IS NOT NULL, (EXISTS (SELECT TRUE FROM BugTask AS RelatedBugTask WHERE RelatedBugTask.bug = BugTask.bug AND RelatedBugTask.id != BugTask.id AND ((RelatedBugTask.bugwatch IS NOT NULL AND RelatedBugTask.status IN (17, 25, 30)) OR (RelatedBugTask.product IS NOT NULL AND RelatedBugTask.bugwatch IS NULL AND RelatedBugTask.status IN (25, 30))))) This is 2 seconds hot, 20 seconds with only the bugtask2 table hot. GroupAggregate (cost=23292297.50..23292303.95 rows=1 width=24) (actual time=1832.353..1881.528 rows=123 loops=1) -> Sort (cost=23292297.50..23292297.51 rows=1 width=24) (actual time=1780.791..1800.321 rows=81522 loops=1) Sort Key: bugtask.status, bugtask.importance, ((bugtask.latest_patch_uploaded IS NOT NULL)), ((SubPlan 1)) Sort Method: quicksort Memory: 9441kB -> Seq Scan on bugtask2 bugtask (cost=0.00..23292297.49 rows=1 width=24) (actual time=0.069..1657.116 rows=81522 loops=1) Filter: ((duplicateof IS NULL) AND (distribution = 1) AND ((status = 10) OR (status = 15) OR (status = 20) OR (status = 21) OR (status = 22) OR (status = 25)) AND ((NOT private) OR (alternatives: SubPlan 2 or hashed SubPlan 3))) SubPlan 1 -> Index Scan using bugtask__bug__idx on bugtask relatedbugtask (cost=0.00..6.42 rows=1 width=0) (actual time=0.008..0.008 rows=0 loops=81522) Index Cond: (bug = $0) Filter: ((id <> $1) AND (((bugwatch IS NOT NULL) AND (status = ANY ('{17,25,30}'::integer[]))) OR ((product IS NOT NULL) AND (bugwatch IS NULL) AND (status = ANY ('{25,30}'::integer[]))))) SubPlan 2 -> Nested Loop (cost=0.00..26.48 rows=1 width=0) (actual time=0.028..0.028 rows=0 loops=7928) -> Index Scan using bugsubscription_bug_idx on bugsubscription (cost=0.00..7.26 rows=3 width=4) (actual time=0.009..0.011 rows=3 loops=7928) Index Cond: (bug = $0) -> Index Scan using teamparticipation_team_key on teamparticipation (cost=0.00..6.39 rows=1 width=4) (actual time=0.004..0.004 rows=0 loops=27709) Index Cond: ((public.teamparticipation.team = public.bugsubscription.person) AND (public.teamparticipation.person = 3199329)) SubPlan 3 -> Nested Loop (cost=0.00..406.26 rows=537 width=4) (never executed) -> Index Scan using teamparticipation_person_idx on teamparticipation (cost=0.00..39.46 rows=14 width=4) (never executed) Index Cond: (person = 3199329) -> Index Scan using bugsubscription_person_idx on bugsubscription (cost=0.00..26.07 rows=10 width=8) (never executed) Index Cond: (public.bugsubscription.person = public.teamparticipation.team) Total runtime: 1881.775 ms