Ща, объясню.
Мне непонятно, почему, если есть хоть какое то ограничение, а в моем случае по content_id, сначала выполняется агрегатная функция по всему представлению, а потом уже только идет отсчение по услови. Даже если подзапрос возвращает много записей, все равно ведь экономней будет сначала применить условие? или нет?
Что собственно и делается, если вместо подзапроса прописать константу.
вот, кстати, план выполнения запроса, при возврате 3 записей из подзапроса:
code:
"Aggregate (cost=70619.42..70619.43 rows=1 width=32)"
" -> Merge IN Join (cost=70202.92..70619.41 rows=2 width=32)"
" Merge Cond: (content_news_clicks.content_id = c.content_id)"
" -> GroupAggregate (cost=70028.75..70296.35 rows=11893 width=24)"
" -> Sort (cost=70028.75..70058.49 rows=11893 width=24)"
" Sort Key: content.content_id, content.stamp"
" -> Merge Join (cost=67636.90..69223.73 rows=11893 width=24)"
" Merge Cond: (content.content_id = counter_daily."object")"
" Join Filter: (counter_daily."day" < (content.stamp + '14 days'::interval))"
" -> Sort (cost=54642.41..54965.95 rows=129415 width=16)"
" Sort Key: content.content_id"
" -> Seq Scan on content (cost=0.00..41218.01 rows=129415 width=16)"
" Filter: (content_role = 2)"
" -> Sort (cost=12994.49..13196.89 rows=80963 width=16)"
" Sort Key: counter_daily."object""
" -> Seq Scan on counter_daily (cost=0.00..4871.49 rows=80963 width=16)"
" Filter: (object_type = 1)"
" -> Sort (cost=174.17..174.28 rows=43 width=8)"
" Sort Key: c.content_id"
" -> Bitmap Heap Scan on content c (cost=4.72..173.00 rows=43 width=8)"
" Recheck Cond: ((stamp >= '2009-07-31 00:00:00'::timestamp without time zone) AND (stamp < '2009-07-31 08:00:00'::timestamp without time zone))"
" -> Bitmap Index Scan on content_stamp_idx (cost=0.00..4.71 rows=43 width=0)"
" Index Cond: ((stamp >= '2009-07-31 00:00:00'::timestamp without time zone) AND (stamp < '2009-07-31 08:00:00'::timestamp without time zone))"
Принципиально ничего не изменилось
А если руками как константу прописать 4000 записей, то все равно выполняется быстро, и отсечение по условию идет до применения арегатной функции, вот план запроса(немного усеченный ):
code:
"Aggregate (cost=58027.35..58027.36 rows=1 width=32)"
" -> HashAggregate (cost=58023.17..58025.26 rows=167 width=24)"
" -> Merge Join (cost=57600.52..58021.92 rows=167 width=24)"
" Merge Cond: (content.content_id = counter_daily."object")"
" Join Filter: (counter_daily."day" < (content.stamp + '14 days'::interval))"
" -> Sort (cost=44606.03..44610.57 rows=1816 width=16)"
" Sort Key: content.content_id"
" -> Bitmap Heap Scan on content (cost=11218.56..44507.72 rows=1816 width=16)"
" Recheck Cond: (content_id = ANY ('{341846,341847,341854,341855,341858,341859,341860,341861,341832,341845,341844,341850,341856,341862,341863,341864,341833,341834,341836,341838,341839,341842,341843,341848,341852,341853,341857,341837,341849,341851,341865,341841,341840,341870,341872,341866,341869,341868,341873,341874,341871,341875,341876,341877}'::bigint[]))"
" Filter: (content_role = 2)"
" -> Bitmap Index Scan on content_pkey (cost=0.00..11218.10 rows=4122 width=0)"
" Index Cond: (content_id = ANY ('{341846,341847,341854,341855,341858,341859,341860,341861,341832,341845,341844,341850,341856,341862,341863,341864,341833,341834,341836,341838,341839,341842,341843,341848,341852,341853,341857,341837,341849,341851,341865,341841,341840,341870,341872,341866,341869,341868,341873,341874,341871,341875,341876,341877}'::bigint[]))"
" -> Sort (cost=12994.49..13196.89 rows=80963 width=16)"
" Sort Key: counter_daily."object""
" -> Seq Scan on counter_daily (cost=0.00..4871.49 rows=80963 width=16)"
" Filter: (object_type = 1)"