And with the product constraint its still reasonable:
explain analyze SELECT count(*) from (SELECT DISTINCT ON (BugTask.id) BugTask.*
FROM BugTask left join product on bugtask.product = product.id, Bug, BugMessage
WHERE
Bug.id = BugTask.bug
AND Bug.id = BugMessage.bug
AND BugTask.status in (10, 15, 20, 21, 22, 25)
AND Bug.duplicateof IS NULL
AND Bug.private = FALSE
AND BugMessage.index > 0
AND BugMessage.owner = 100
and (bugtask.product is null or product.active)) as foo;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=195766.06..195766.07 rows=1 width=0) (actual time=503.638..503.638 rows=1 loops=1)
-> Unique (cost=195578.95..195632.41 rows=10692 width=415) (actual time=500.720..503.337 rows=2032 loops=1)
-> Sort (cost=195578.95..195605.68 rows=10692 width=415) (actual time=500.718..501.538 rows=5285 loops=1)
Sort Key: bugtask.id
Sort Method: quicksort Memory: 2316kB
-> Nested Loop (cost=501.86..194863.43 rows=10692 width=415) (actual time=23.042..485.416 rows=5285 loops=1) -> Nested Loop Left Join (cost=501.86..132222.15 rows=10692 width=419) (actual time=23.017..431.153 rows=6724 loops=1) Filter: ((bugtask.product IS NULL) OR product.active) -> Nested Loop (cost=501.86..128582.62 rows=11730 width=419) (actual time=22.994..413.474 rows=6733 loops=1) -> Bitmap Heap Scan on bugmessage (cost=501.86..36012.55 rows=26663 width=4) (actual time=22.862..76.690 rows=32134 loops=1) Recheck Cond: ((owner = 100) AND (index > 0)) -> Bitmap Index Scan on bugmessage__owner__index__idx (cost=0.00..495.20 rows=26663 width=0) (actual time=15.267..15.267 rows=32134 loops=1) Index Cond: ((owner = 100) AND (index > 0)) -> Index Scan using bugtask__bug__idx on bugtask (cost=0.00..3.46 rows=1 width=415) (actual time=0.009..0.010 rows=0 loops=32134) Index Cond: (bugtask.bug = bugmessage.bug) Filter: (bugtask.status = ANY ('{10,15,20,21,22,25}'::integer[])) -> Index Scan using product_pkey on product (cost=0.00..0.30 rows=1 width=5) (actual time=0.001..0.001 rows=0 loops=6733) Index Cond: (bugtask.product = product.id) -> Index Scan using bug_pkey on bug (cost=0.00..5.85 rows=1 width=4) (actual time=0.007..0.007 rows=1 loops=6724) Index Cond: (bug.id = bugtask.bug) Filter: ((bug.duplicateof IS NULL) AND (NOT bug.private))
Total runtime: 504.301 ms
(22 rows)
And with the product constraint its still reasonable:
explain analyze SELECT count(*) from (SELECT DISTINCT ON (BugTask.id) BugTask.*
FROM BugTask left join product on bugtask.product = product.id, Bug, BugMessage
WHERE
Bug.id = BugTask.bug
AND Bug.id = BugMessage.bug
AND BugTask.status in (10, 15, 20, 21, 22, 25)
AND Bug.duplicateof IS NULL
AND Bug.private = FALSE
AND BugMessage.index > 0
AND BugMessage.owner = 100
and (bugtask.product is null or product.active)) as foo;
-------
Aggregate (cost=195766.
-> Unique (cost=195578.
-> Sort (cost=195578.
Sort Key: bugtask.id
Sort Method: quicksort Memory: 2316kB
-> Nested Loop (cost=501.
Total runtime: 504.301 ms
(22 rows)