рд╡реЗрд│реЛрд╡реЗрд│реА, рдХрд│рд╛рдВрдЪреНрдпрд╛ рд╕рдВрдЪрд╛рджреНрд╡рд╛рд░реЗ рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рд╢реЛрдзрдгреНрдпрд╛рдЪреЗ рдХрд╛рдо рдЙрджреНрднрд╡рддреЗ, рдЬреЛрдкрд░реНрдпрдВрдд рдЖрдкрдг рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдПрдХреВрдг рдиреЛрдВрджреАрдВрдЪреА рд╕рдВрдЦреНрдпрд╛ рдЧрд╛рдардд рдирд╛рд╣реА рддреЛрдкрд░реНрдпрдВрдд.
рд╕рд░реНрд╡рд╛рдд "рд╡рд╛рд╕реНрддрд╡рд┐рдХ" рдЙрджрд╛рд╣рд░рдг рдореНрд╣рдгрдЬреЗ рдирд┐рд╖реНрдХрд░реНрд╖ рдХрд╛рдврдгреЗ реиреж рд╕рд░реНрд╡рд╛рдд рдЬреБрдиреА рдХрд╛рдореЗ, рд╕реВрдЪреАрдмрджреНрдз рдХрд░реНрдордЪрд╛рд▒реНрдпрд╛рдВрдЪреНрдпрд╛ рдпрд╛рджреАрдд (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдПрдХрд╛рдЪ рд╡рд┐рднрд╛рдЧрд╛рдд). рдХрд╛рд░реНрдпрдХреНрд╖реЗрддреНрд░рд╛рдВрдЪрд╛ рдереЛрдбрдХреНрдпрд╛рдд рд╕рд╛рд░рд╛рдВрд╢ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╡рд┐рд╡рд┐рдз рд╡реНрдпрд╡рд╕реНрдерд╛рдкрди рдбреЕрд╢рдмреЛрд░реНрдбрд╕рд╛рдареА, рдмрд╣реБрддреЗрдХрджрд╛ рд╕рдорд╛рди рдереАрдо рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рддреЗ.

рдпрд╛ рд▓реЗрдЦрд╛рдд, рдЖрдкрдг PostgreSQL рдордзреНрдпреЗ рдпрд╛ рд╕рдорд╕реНрдпреЗрд╡рд░ "рднреЛрд│реЗ" рдЙрдкрд╛рдп рд▓рд╛рдЧреВ рдХрд░рдгреНрдпрд╛рдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░реВ, рдЬреЛ "рдЕрдзрд┐рдХ рд╕реНрдорд╛рд░реНрдЯ" рдЖрдгрд┐ рдЕрддрд┐рд╢рдп рдЬрдЯрд┐рд▓ рдЕрд▓реНрдЧреЛрд░рд┐рдердо рдЖрд╣реЗ. рд╕рд╛рдкрдбрд▓реЗрд▓реНрдпрд╛ рдбреЗрдЯрд╛рд╡рд░ рдЖрдзрд╛рд░рд┐рдд рдПрдХреНрдЭрд┐рдЯ рдХрдВрдбрд┐рд╢рдирд╕рд╣ SQL рдордзреНрдпреЗ "рд▓реВрдк"., рдЬреЗ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдХрд╛рд╕рд╛рд╕рд╛рдареА рдЖрдгрд┐ рдЗрддрд░ рддрддреНрд╕рдо рдкреНрд░рдХрд░рдгрд╛рдВрдордзреНрдпреЗ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЙрдкрдпреБрдХреНрдд рдард░реВ рд╢рдХрддреЗ.
рдЪрд▓рд╛ рдПрдХ рдЪрд╛рдЪрдгреА рдбреЗрдЯрд╛ рд╕реЗрдЯ рдШреЗрдКрдпрд╛ рдХреНрд░рдорд╡рд╛рд░реА рд▓рд╛рд╡рд▓реЗрд▓реНрдпрд╛ рдореВрд▓реНрдпрд╛рдВрд╢реА рдЬреБрд│рддрд╛рдирд╛ рдЖрдЙрдЯрдкреБрдЯ рд░реЗрдХреЙрд░реНрдб рдПрдХрд╛ рд╡реЗрд│реЗрдкрд╛рд╕реВрди рджреБрд╕рд▒реНрдпрд╛ рд╡реЗрд│реА "рдЙрдбреА рдорд╛рд░рдгреНрдпрд╛рдкрд╛рд╕реВрди" рд░реЛрдЦрдгреНрдпрд╛рд╕рд╛рдареА, рдЪрд▓рд╛ рдкреНрд░рд╛рдердорд┐рдХ рдХреА рдЬреЛрдбреВрди рд╡рд┐рд╖рдп рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╡рд╛рдврд╡реВрдпрд╛.рд╣реЗ рддрд╛рдмрдбрддреЛрдм рддреЗ рдЕрджреНрд╡рд┐рддреАрдп рдмрдирд╡реЗрд▓ рдЖрдгрд┐ рд╕реНрдкрд╖реНрдЯ рдХреНрд░рдорд╡рд╛рд░реАрдЪреА рд╣рдореА рджреЗрдИрд▓:
CREATE INDEX ON task(owner_id, task_date, id);
-- ╨░ ╤Б╤В╨░╤А╤Л╨╣ - ╤Г╨┤╨░╨╗╨╕╨╝
DROP INDEX task_owner_id_task_date_idx;рддреЗ рдЬрд╕реЗ рд╡рд╛рдЯрддреЗ рддрд╕реЗ рд▓рд┐рд╣рд┐рд▓реЗ рдЖрд╣реЗ.
рдкреНрд░рдердо, рд╡рд┐рдирдВрддреАрдЪреА рд╕рд░реНрд╡рд╛рдд рд╕реЛрдкреА рдЖрд╡реГрддреНрддреА рд░реЗрдЦрд╛рдЯреВрдпрд╛, рдХрд▓рд╛рдХрд╛рд░рд╛рдВрдЪреЗ рдЖрдпрдбреА рдкрд╛рд╕ рдХрд░реВрдпрд╛. :
SELECT
*
FROM
task
WHERE
owner_id = ANY('{1,2,4,8,16,32,64,128,256,512}'::integer[])
ORDER BY
task_date, id
LIMIT 20; 
рд╣реЗ рдереЛрдбреЗ рджреБрдГрдЦрдж рдЖрд╣реЗ - рдЖрдореНрд╣реА рдлрдХреНрдд реиреж рд░реЗрдХреЙрд░реНрдб рдСрд░реНрдбрд░ рдХреЗрд▓реЗ рдЖрдгрд┐ рдЗрдВрдбреЗрдХреНрд╕ рд╕реНрдХреЕрдирдиреЗ рддреЗ рдЖрдореНрд╣рд╛рд▓рд╛ рдкрд░рдд рдХреЗрд▓реЗ. репремреж рдУрд│реА, рдЬреЗ рдирдВрддрд░ рдХреНрд░рдорд╡рд╛рд░реА рд▓рд╛рд╡рд╛рд╡реЗ рд▓рд╛рдЧрд▓реЗ... рдЪрд▓рд╛ рдХрдореА рд╡рд╛рдЪрдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВрдпрд╛.
рдЕрдирдиреЗрд╕реНрдЯ + рдЕтАНреЕрд░реЗ
рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдорджрдд рдХрд░рдгрд╛рд░рд╛ рдкрд╣рд┐рд▓рд╛ рд╡рд┐рдЪрд╛рд░ рдореНрд╣рдгрдЬреЗ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдЧрд░рдЬ рдЖрд╣реЗ рдХрд╛ рдлрдХреНрдд реиреж рдХреНрд░рдорд╡рд╛рд░реА рд▓рд╛рд╡рд▓реА рд░реЗрдХреЙрд░реНрдб, рдирдВрддрд░ рддреЗ рд╡рд╛рдЪрдгреНрдпрд╛рд╕рд╛рдареА рдкреБрд░реЗрд╕реЗ рдЖрд╣реЗ рдкреНрд░рддреНрдпреЗрдХрд╛рд╕рд╛рдареА рдПрдХрд╛рдЪ рдХреНрд░рдорд╛рдиреЗ реиреж рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдирд╛рд╣реА. рдХреА. рд╕реБрджреИрд╡рд╛рдиреЗ, рдпреЛрдЧреНрдп рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ (рдорд╛рд▓рдХ_рдЖрдпрдбреА, рдХрд╛рд░реНрдп_рддрд╛рд░реАрдЦ, рдЖрдпрдбреА) рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдЖрд╣реЗ.
рдЪрд▓рд╛ рдХрд╛рдврдгреНрдпрд╛рдЪреА рдЖрдгрд┐ "рд╕реНрддрдВрднрд╛рдВрдордзреНрдпреЗ рдЙрд▓рдЧрдбрдгреНрдпрд╛рдЪреА" рд╕рдорд╛рди рдпрдВрддреНрд░рдгрд╛ рд╡рд╛рдкрд░реВрдпрд╛. рдЗрдВрдЯрд┐рдЧреНрд░рд▓ рдЯреЗрдмрд▓ рдПрдВрдЯреНрд░реА, рдЬрд╕реЗ рдХреА . рдЖрдкрдг рдлрдВрдХреНрд╢рди рд╡рд╛рдкрд░реВрди рдЕтАНреЕрд░реЗрдордзреНрдпреЗ рдлреЛрд▓реНрдбрд┐рдВрдЧ рджреЗрдЦреАрд▓ рд▓рд╛рдЧреВ рдХрд░реВ. ARRAY():
WITH T AS (
SELECT
unnest(ARRAY(
SELECT
t
FROM
task t
WHERE
owner_id = unnest
ORDER BY
task_date, id
LIMIT 20 -- ╨╛╨│╤А╨░╨╜╨╕╤З╨╕╨▓╨░╨╡╨╝ ╤В╤Г╤В...
)) r
FROM
unnest('{1,2,4,8,16,32,64,128,256,512}'::integer[])
)
SELECT
(r).*
FROM
T
ORDER BY
(r).task_date, (r).id
LIMIT 20; -- ... ╨╕ ╤В╤Г╤В - ╤В╨╛╨╢╨╡ 
рдЕрд░реЗ, рддреЗ рддрд░ рдЦреВрдкрдЪ рдЪрд╛рдВрдЧрд▓реЗ рдЖрд╣реЗ! рекреж% рдЬрд▓рдж рдЖрдгрд┐ рек.рел рдкрдЯ рдХрдореА рдбреЗрдЯрд╛ рдорд▓рд╛ рддреЗ рд╡рд╛рдЪрд╛рд╡реЗ рд▓рд╛рдЧрд▓реЗ.
CTE рджреНрд╡рд╛рд░реЗ рдЯреЗрдмрд▓ рд░реЗрдХреЙрд░реНрдбрдЪреЗ рднреМрддрд┐рдХреАрдХрд░рдгрдореА рддреБрдордЪреЗ рд▓рдХреНрд╖ рдпрд╛ рд╡рд╕реНрддреБрд╕реНрдерд┐рддреАрдХрдбреЗ рд╡реЗрдзреВ рдЗрдЪреНрдЫрд┐рддреЛ рдХреА рдХрд╛рд╣реА рдмрд╛рдмрддреАрдд рд╕рдмрдХреНрд╡реЗрд░реАрдордзреНрдпреЗ рд░реЗрдХреЙрд░реНрдб рдлреАрд▓реНрдб рд╢реЛрдзрд▓реНрдпрд╛рдирдВрддрд░, рддреЗ CTE рдордзреНрдпреЗ "рд░реЕрдкрд┐рдВрдЧ" рди рдХрд░рддрд╛ рд▓рдЧреЗрдЪ рддреНрдпрд╛рд╡рд░ рдХрд╛рдо рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХреЗрд▓реНрдпрд╛рд╕, InitPlan рдЪреЗ "рдЧреБрдгрд╛рдХрд╛рд░" рдпрд╛ рд╕рдорд╛рди рдлреАрд▓реНрдбрдЪреНрдпрд╛ рд╕рдВрдЦреНрдпреЗрдЪреНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рдд:
SELECT
((
SELECT
t
FROM
task t
WHERE
owner_id = 1
ORDER BY
task_date, id
LIMIT 1
).*);Result (cost=4.77..4.78 rows=1 width=16) (actual time=0.063..0.063 rows=1 loops=1)
Buffers: shared hit=16
InitPlan 1 (returns $0)
-> Limit (cost=0.42..1.19 rows=1 width=48) (actual time=0.031..0.032 rows=1 loops=1)
Buffers: shared hit=4
-> Index Scan using task_owner_id_task_date_id_idx on task t (cost=0.42..387.57 rows=500 width=48) (actual time=0.030..0.030 rows=1 loops=1)
Index Cond: (owner_id = 1)
Buffers: shared hit=4
InitPlan 2 (returns $1)
-> Limit (cost=0.42..1.19 rows=1 width=48) (actual time=0.008..0.009 rows=1 loops=1)
Buffers: shared hit=4
-> Index Scan using task_owner_id_task_date_id_idx on task t_1 (cost=0.42..387.57 rows=500 width=48) (actual time=0.008..0.008 rows=1 loops=1)
Index Cond: (owner_id = 1)
Buffers: shared hit=4
InitPlan 3 (returns $2)
-> Limit (cost=0.42..1.19 rows=1 width=48) (actual time=0.008..0.008 rows=1 loops=1)
Buffers: shared hit=4
-> Index Scan using task_owner_id_task_date_id_idx on task t_2 (cost=0.42..387.57 rows=500 width=48) (actual time=0.008..0.008 rows=1 loops=1)
Index Cond: (owner_id = 1)
Buffers: shared hit=4"
InitPlan 4 (returns $3)
-> Limit (cost=0.42..1.19 rows=1 width=48) (actual time=0.009..0.009 rows=1 loops=1)
Buffers: shared hit=4
-> Index Scan using task_owner_id_task_date_id_idx on task t_3 (cost=0.42..387.57 rows=500 width=48) (actual time=0.009..0.009 rows=1 loops=1)
Index Cond: (owner_id = 1)
Buffers: shared hit=4
рддреЛрдЪ рд░реЗрдХреЙрд░реНрдб рек рд╡реЗрд│рд╛ "рд╢реЛрдзрд▓рд╛" рдЧреЗрд▓рд╛... PostgreSQL резрез рдкрд░реНрдпрдВрдд, рд╣реЗ рд╡рд░реНрддрди рдирд┐рдпрдорд┐рддрдкрдгреЗ рдЖрдврд│рдд рд╣реЛрддреЗ рдЖрдгрд┐ рддреНрдпрд╛рд╡рд░ рдЙрдкрд╛рдп рдореНрд╣рдгрдЬреЗ рддреЗ CTE рдордзреНрдпреЗ "рд░реЕрдк" рдХрд░рдгреЗ, рдЬреЗ рдпрд╛ рдЖрд╡реГрддреНрддреНрдпрд╛рдВрдордзреНрдпреЗ рдСрдкреНрдЯрд┐рдорд╛рдпрдЭрд░рд╕рд╛рдареА рдПрдХ рдкрд░рд┐рдкреВрд░реНрдг рдорд░реНрдпрд╛рджрд╛ рдЖрд╣реЗ.
рд░рд┐рдХрд░реНрд╕рд┐рд╡реНрд╣ рдЕтАНреЕрдХреНрдпреБрдореНрдпреБрд▓реЗрдЯрд░
рдорд╛рдЧреАрд▓ рдЖрд╡реГрддреНрддреАрдд, рдЖрдкрдг рдПрдХреВрдг рд╡рд╛рдЪрд▓реЗ репремреж рдУрд│реА рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ реиреж рд╕рд╛рдареА. рдЖрддрд╛ репремреж рдирд╛рд╣реА, рддрд░ рддреНрдпрд╛рд╣реВрдирд╣реА рдХрдореА - рд╣реЗ рд╢рдХреНрдп рдЖрд╣реЗ рдХрд╛?
рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реЗрд▓реЗ рдЬреНрдЮрд╛рди рд╡рд╛рдкрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВрдпрд╛ рдПрдХреВрдг 20 рд░реЗрдХреЙрд░реНрдб. рдореНрд╣рдгрдЬреЗрдЪ, рдЖрдкрдг рдЖрд╡рд╢реНрдпрдХ рд╕рдВрдЦреНрдпреЗрдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪреЗрдкрд░реНрдпрдВрддрдЪ рдбреЗрдЯрд╛ рд░реАрдбрд┐рдВрдЧрдЪреА рдкреБрдирд░рд╛рд╡реГрддреНрддреА рдХрд░реВ.
рдкрд╛рдпрд░реА рез: рд╕реБрд░реБрд╡рд╛рддреАрдЪреА рдпрд╛рджреА
рдЕрд░реНрдерд╛рдд, рдЖрдордЪреА реиреж рд░реЗрдХреЙрд░реНрдбрдЪреА "рд▓рдХреНрд╖реНрдп" рдпрд╛рджреА рдЖрдордЪреНрдпрд╛ рдорд╛рд▓рдХ_рдЖрдпрдбреА рдХреА рдкреИрдХреА рдПрдХрд╛рдЪреНрдпрд╛ "рдкрд╣рд┐рд▓реНрдпрд╛" рд░реЗрдХреЙрд░реНрдбрдиреЗ рд╕реБрд░реВ рдЭрд╛рд▓реА рдкрд╛рд╣рд┐рдЬреЗ. рддрд░, рдкреНрд░рдердо рддреНрдпрд╛ рд╢реЛрдзреВрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдХрд┐рд▓реНрд▓реАрд╕рд╛рдареА "рдкрд╣рд┐рд▓реЗ" рдЖрдгрд┐ рддреЗ рдпрд╛рджреАрдд рдЬреЛрдбрд╛, рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рд╣рд╡реНрдпрд╛ рддреНрдпрд╛ рдХреНрд░рдорд╛рдиреЗ рдХреНрд░рдорд╡рд╛рд░реА рд▓рд╛рд╡рд╛ - (рдХрд╛рд░реНрдп_рддрд╛рд░реАрдЦ, рдЖрдпрдбреА).

рдкрд╛рдпрд░реА реи: "рдкреБрдвреАрд▓" рдиреЛрдВрджреА рд╢реЛрдзрд╛
рдЖрддрд╛ рдЬрд░ рдЖрдкрдг рдЖрдкрд▓реНрдпрд╛ рдпрд╛рджреАрддреАрд▓ рдкрд╣рд┐рд▓реА рдиреЛрдВрдж рдШреЗрддрд▓реА рдЖрдгрд┐ рд╕реБрд░реБрд╡рд╛рдд рдХреЗрд▓реА рддрд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХрд╛рдд рдЖрдгрдЦреА "рдкрд╛рдп" рдЯрд╛рдХрд╛ рдорд╛рд▓рдХ_рдЖрдпрдбреА рдХреА рдЬрддрди рдХрд░реВрди, рд╕рд╛рдкрдбрд▓реЗрд▓реЗ рд╕рд░реНрд╡ рд░реЗрдХреЙрд░реНрдб рдкрд░рд┐рдгрд╛рдореА рдирд┐рд╡рдбреАрддреАрд▓ рдЕрдЧрджреА рдкреБрдвреАрд▓ рд░реЗрдХреЙрд░реНрдб рдЕрд╕рддреАрд▓. рдЕрд░реНрдерд╛рдд, рдлрдХреНрдд рдЬреЛрдкрд░реНрдпрдВрдд рдЖрдкрдг рд▓рд╛рдЧреВ рдХреЗрд▓реЗрд▓реА рдХреА рдУрд▓рд╛рдВрдбрдд рдирд╛рд╣реА рддреЛрдкрд░реНрдпрдВрдд рдпрд╛рджреАрддреАрд▓ рджреБрд╕рд░реА рдиреЛрдВрдж.
рдЬрд░ рдЕрд╕реЗ рджрд┐рд╕реВрди рдЖрд▓реЗ рдХреА рдЖрдкрдг рджреБрд╕рд░реА рдиреЛрдВрдж "рдХреНрд░реЙрд╕" рдХреЗрд▓реА, рддрд░ рдкрд╣рд┐рд▓реНрдпрд╛рдРрд╡рдЬреА рд╢реЗрд╡рдЯрдЪреА рд╡рд╛рдЪрд▓реЗрд▓реА рдиреЛрдВрдж рдпрд╛рджреАрдд рдЬреЛрдбрд╛рд╡реА. (рддреНрдпрд╛рдЪ рдорд╛рд▓рдХрд╛рдЪреНрдпрд╛_рдЖрдпрдбреАрд╕рд╣), рддреНрдпрд╛рдирдВрддрд░ рдЖрдореНрд╣реА рдпрд╛рджреА рдкреБрдиреНрд╣рд╛ рдХреНрд░рдорд╡рд╛рд░реА рд▓рд╛рд╡рддреЛ.

рдореНрд╣рдгрдЬреЗрдЪ, рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдиреЗрд╣рдореАрдЪ рдЕрд╕реЗ рдЖрдврд│рддреЗ рдХреА рдпрд╛рджреАрдордзреНрдпреЗ рдкреНрд░рддреНрдпреЗрдХ рдХреАрд╕рд╛рдареА рдПрдХрд╛рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдиреЛрдВрджреА рдирд╛рд╣реАрдд (рдЬрд░ рдиреЛрдВрджреА рд╕рдВрдкрд▓реНрдпрд╛ рдЖрдгрд┐ рдЖрдкрдг рддреНрдпрд╛ "рдХреНрд░реЙрд╕" рдХреЗрд▓реНрдпрд╛ рдирд╛рд╣реАрдд, рддрд░ рдкрд╣рд┐рд▓реА рдиреЛрдВрдж рдпрд╛рджреАрддреВрди рдЧрд╛рдпрдм рд╣реЛрдИрд▓ рдЖрдгрд┐ рдХрд╛рд╣реАрд╣реА рдЬреЛрдбрд▓реЗ рдЬрд╛рдгрд╛рд░ рдирд╛рд╣реА), рдЖрдгрд┐ рддреЗ рдиреЗрд╣рдореА рдХреНрд░рдорд╡рд╛рд░реА рд▓рд╛рд╡рд▓реЗрд▓реЗ рдЕреЕрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА (рдЯрд╛рд╕реНрдХ_рдбреЗрдЯ, рдЖрдпрдбреА) рдЪреНрдпрд╛ рдЪрдврддреНрдпрд╛ рдХреНрд░рдорд╛рдиреЗ.

рдкрд╛рдпрд░реА рей: рд░реЗрдХреЙрд░реНрдб рдлрд┐рд▓реНрдЯрд░ рдХрд░рд╛ рдЖрдгрд┐ рд╡рд┐рд╕реНрддреГрдд рдХрд░рд╛
рдЖрдордЪреНрдпрд╛ рд░рд┐рдХрд░реНрд╕рд┐рд╡реНрд╣ рдирд┐рд╡рдбреАрдЪреНрдпрд╛ рдХрд╛рд╣реА рдУрд│реАрдВрдордзреНрдпреЗ, рдХрд╛рд╣реА рдиреЛрдВрджреА rv рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдиреЛрдВрджреА - рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдкреНрд░рдердо "рдпрд╛рджреАрддреАрд▓ рджреБрд╕рд▒реНрдпрд╛ рдиреЛрдВрджреАрдЪреА рд╕реАрдорд╛ рдУрд▓рд╛рдВрдбрдгреЗ" рд╕рд╛рд░рдЦреНрдпрд╛ рдиреЛрдВрджреА рдЖрдврд│рддрд╛рдд рдЖрдгрд┐ рдирдВрддрд░ рддреНрдпрд╛ рдпрд╛рджреАрддреАрд▓ рдкрд╣рд┐рд▓реНрдпрд╛ рдиреЛрдВрджреА рдореНрд╣рдгреВрди рдмрджрд▓рддрд╛рдд. рдореНрд╣рдгреВрди, рдкрд╣рд┐рд▓реА рдШрдЯрдирд╛ рдлрд┐рд▓реНрдЯрд░ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.
рднрдпрд╛рдирдХ рд╢реЗрд╡рдЯрдЪрд╛ рдкреНрд░рд╢реНрди
WITH RECURSIVE T AS (
-- #1 : ╨╖╨░╨╜╨╛╤Б╨╕╨╝ ╨▓ ╤Б╨┐╨╕╤Б╨╛╨║ "╨┐╨╡╤А╨▓╤Л╨╡" ╨╖╨░╨┐╨╕╤Б╨╕ ╨┐╨╛ ╨║╨░╨╢╨┤╨╛╨╝╤Г ╨╕╨╖ ╨║╨╗╤О╤З╨╡╨╣ ╨╜╨░╨▒╨╛╤А╨░
WITH wrap AS ( -- "╨╝╨░╤В╨╡╤А╨╕╨░╨╗╨╕╨╖╤Г╨╡╨╝" record'╤Л, ╤З╤В╨╛╨▒╤Л ╨╛╨▒╤А╨░╤Й╨╡╨╜╨╕╨╡ ╨║ ╨┐╨╛╨╗╤П╨╝ ╨╜╨╡ ╨▓╤Л╨╖╤Л╨▓╨░╨╗╨╛ ╤Г╨╝╨╜╨╛╨╢╨╡╨╜╨╕╤П InitPlan/SubPlan
WITH T AS (
SELECT
(
SELECT
r
FROM
task r
WHERE
owner_id = unnest
ORDER BY
task_date, id
LIMIT 1
) r
FROM
unnest('{1,2,4,8,16,32,64,128,256,512}'::integer[])
)
SELECT
array_agg(r ORDER BY (r).task_date, (r).id) list -- ╤Б╨╛╤А╤В╨╕╤А╤Г╨╡╨╝ ╤Б╨┐╨╕╤Б╨╛╨║ ╨▓ ╨╜╤Г╨╢╨╜╨╛╨╝ ╨┐╨╛╤А╤П╨┤╨║╨╡
FROM
T
)
SELECT
list
, list[1] rv
, FALSE not_cross
, 0 size
FROM
wrap
UNION ALL
-- #2 : ╨▓╤Л╤З╨╕╤В╤Л╨▓╨░╨╡╨╝ ╨╖╨░╨┐╨╕╤Б╨╕ 1-╨│╨╛ ╨┐╨╛ ╨┐╨╛╤А╤П╨┤╨║╤Г ╨║╨╗╤О╤З╨░, ╨┐╨╛╨║╨░ ╨╜╨╡ ╨┐╨╡╤А╨╡╤И╨░╨│╨╜╨╡╨╝ ╤З╨╡╤А╨╡╨╖ ╨╖╨░╨┐╨╕╤Б╤М 2-╨│╨╛
SELECT
CASE
-- ╨╡╤Б╨╗╨╕ ╨╜╨╕╤З╨╡╨│╨╛ ╨╜╨╡ ╨╜╨░╨╣╨┤╨╡╨╜╨╛ ╨┤╨╗╤П ╨║╨╗╤О╤З╨░ 1-╨╣ ╨╖╨░╨┐╨╕╤Б╨╕
WHEN X._r IS NOT DISTINCT FROM NULL THEN
T.list[2:] -- ╤Г╨▒╨╕╤А╨░╨╡╨╝ ╨╡╨╡ ╨╕╨╖ ╤Б╨┐╨╕╤Б╨║╨░
-- ╨╡╤Б╨╗╨╕ ╨╝╤Л ╨Э╨Х ╨┐╨╡╤А╨╡╤Б╨╡╨║╨╗╨╕ ╨┐╤А╨╕╨║╨╗╨░╨┤╨╜╨╛╨╣ ╨║╨╗╤О╤З 2-╨╣ ╨╖╨░╨┐╨╕╤Б╨╕
WHEN X.not_cross THEN
T.list -- ╨┐╤А╨╛╤Б╤В╨╛ ╨┐╤А╨╛╤В╤П╨│╨╕╨▓╨░╨╡╨╝ ╤В╨╛╤В ╨╢╨╡ ╤Б╨┐╨╕╤Б╨╛╨║ ╨▒╨╡╨╖ ╨╝╨╛╨┤╨╕╤Д╨╕╨║╨░╤Ж╨╕╨╣
-- ╨╡╤Б╨╗╨╕ ╨▓ ╤Б╨┐╨╕╤Б╨║╨╡ ╤Г╨╢╨╡ ╨╜╨╡╤В 2-╨╣ ╨╖╨░╨┐╨╕╤Б╨╕
WHEN T.list[2] IS NULL THEN
-- ╨┐╤А╨╛╤Б╤В╨╛ ╨▓╨╛╨╖╨▓╤А╨░╤Й╨░╨╡╨╝ ╨┐╤Г╤Б╤В╨╛╨╣ ╤Б╨┐╨╕╤Б╨╛╨║
'{}'
-- ╨┐╨╡╤А╨╡╤Б╨╛╤А╤В╨╕╤А╨╛╨▓╤Л╨▓╨░╨╡╨╝ ╤Б╨╗╨╛╨▓╨░╤А╤М, ╤Г╨▒╨╕╤А╨░╤П 1-╤О ╨╖╨░╨┐╨╕╤Б╤М ╨╕ ╨┤╨╛╨▒╨░╨▓╨╗╤П╤П ╨┐╨╛╤Б╨╗╨╡╨┤╨╜╤О╤О ╨╕╨╖ ╨╜╨░╨╣╨┤╨╡╨╜╨╜╤Л╤Е
ELSE (
SELECT
coalesce(T.list[2] || array_agg(r ORDER BY (r).task_date, (r).id), '{}')
FROM
unnest(T.list[3:] || X._r) r
)
END
, X._r
, X.not_cross
, T.size + X.not_cross::integer
FROM
T
, LATERAL(
WITH wrap AS ( -- "╨╝╨░╤В╨╡╤А╨╕╨░╨╗╨╕╨╖╤Г╨╡╨╝" record
SELECT
CASE
-- ╨╡╤Б╨╗╨╕ ╨▓╤Б╨╡-╤В╨░╨║╨╕ "╨┐╨╡╤А╨╡╤И╨░╨│╨╜╤Г╨╗╨╕" ╤З╨╡╤А╨╡╨╖ 2-╤О ╨╖╨░╨┐╨╕╤Б╤М
WHEN NOT T.not_cross
-- ╤В╨╛ ╨╜╤Г╨╢╨╜╨░╤П ╨╖╨░╨┐╨╕╤Б╤М - ╨┐╨╡╤А╨▓╨░╤П ╨╕╨╖ ╤Б╨┐╨┐╨╕╤Б╨║╨░
THEN T.list[1]
ELSE ( -- ╨╡╤Б╨╗╨╕ ╨╜╨╡ ╨┐╨╡╤А╨╡╤Б╨╡╨║╨╗╨╕, ╤В╨╛ ╨║╨╗╤О╤З ╨╛╤Б╤В╨░╨╗╤Б╤П ╨║╨░╨║ ╨▓ ╨┐╤А╨╡╨┤╤Л╨┤╤Г╤Й╨╡╨╣ ╨╖╨░╨┐╨╕╤Б╨╕ - ╨╛╤В╤В╨░╨╗╨║╨╕╨▓╨░╨╡╨╝╤Б╤П ╨╛╤В ╨╜╨╡╨╡
SELECT
_r
FROM
task _r
WHERE
owner_id = (rv).owner_id AND
(task_date, id) > ((rv).task_date, (rv).id)
ORDER BY
task_date, id
LIMIT 1
)
END _r
)
SELECT
_r
, CASE
-- ╨╡╤Б╨╗╨╕ 2-╨╣ ╨╖╨░╨┐╨╕╤Б╨╕ ╤Г╨╢╨╡ ╨╜╨╡╤В ╨▓ ╤Б╨┐╨╕╤Б╨║╨╡, ╨╜╨╛ ╨╝╤Л ╤Е╨╛╤В╤М ╤З╤В╨╛-╤В╨╛ ╨╜╨░╤И╨╗╨╕
WHEN list[2] IS NULL AND _r IS DISTINCT FROM NULL THEN
TRUE
ELSE -- ╨╜╨╕╤З╨╡╨│╨╛ ╨╜╨╡ ╨╜╨░╤И╨╗╨╕ ╨╕╨╗╨╕ "╨┐╨╡╤А╨╡╤И╨░╨│╨╜╤Г╨╗╨╕"
coalesce(((_r).task_date, (_r).id) < ((list[2]).task_date, (list[2]).id), FALSE)
END not_cross
FROM
wrap
) X
WHERE
T.size < 20 AND -- ╨╛╨│╤А╨░╨╜╨╕╤З╨╕╨▓╨░╨╡╨╝ ╤В╤Г╤В ╨║╨╛╨╗╨╕╤З╨╡╤Б╤В╨▓╨╛
T.list IS DISTINCT FROM '{}' -- ╨╕╨╗╨╕ ╨┐╨╛╨║╨░ ╤Б╨┐╨╕╤Б╨╛╨║ ╨╜╨╡ ╨║╨╛╨╜╤З╨╕╨╗╤Б╤П
)
-- #3 : "╤А╨░╨╖╨▓╨╛╤А╨░╤З╨╕╨▓╨░╨╡╨╝" ╨╖╨░╨┐╨╕╤Б╨╕ - ╨┐╨╛╤А╤П╨┤╨╛╨║ ╨│╨░╤А╨░╨╜╤В╨╕╤А╨╛╨▓╨░╨╜ ╨┐╨╛ ╨┐╨╛╤Б╤В╤А╨╛╨╡╨╜╨╕╤О
SELECT
(rv).*
FROM
T
WHERE
not_cross; -- ╨▒╨╡╤А╨╡╨╝ ╤В╨╛╨╗╤М╨║╨╛ "╨╜╨╡╨┐╨╡╤А╨╡╤Б╨╡╨║╨░╤О╤Й╨╕╨╡" ╨╖╨░╨┐╨╕╤Б╨╕ 
рддрд░ рдЖрдкрдг рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рд╡реЗрд│реЗрдЪреНрдпрд╛ реиреж% рд╕рд╛рдареА релреж% рдбреЗрдЯрд╛ рд░реАрдбрдЪрд╛ рд╡реНрдпрд╛рдкрд╛рд░ рдХреЗрд▓рд╛рдореНрд╣рдгрдЬреЗрдЪ, рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдЕрд╕реЗ рдорд╛рдирдгреНрдпрд╛рдЪреЗ рдХрд╛рд░рдг рдЕрд╕реЗрд▓ рдХреА рд╡рд╛рдЪрди рдордВрдж рдЕрд╕реВ рд╢рдХрддреЗ (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдбреЗрдЯрд╛ рдмрд╣реБрддреЗрдХрджрд╛ рдХреЕрд╢реЗрдордзреНрдпреЗ рдирд╕рддреЛ рдЖрдгрд┐ рдбрд┐рд╕реНрдХрд╡рд░реВрди рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рд╛рд╡рд╛ рд▓рд╛рдЧрддреЛ), рддрд░ рд╣реА рдкрджреНрдзрдд рд╡рд╛рдЪрдирд╛рд╡рд░реАрд▓ рддреБрдордЪрд╛ рдЕрд╡рд▓рдВрдмрд┐рддреНрд╡ рдХрдореА рдХрд░реВ рд╢рдХрддреЗ.
рдХрд╛рд╣реАрд╣реА рдЕрд╕реЛ, "рднреЛрд│реНрдпрд╛" рдкрд╣рд┐рд▓реНрдпрд╛ рдкрд░реНрдпрд╛рдпрд╛рдкреЗрдХреНрд╖рд╛ рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреАрдЪрд╛ рд╡реЗрд│ рдЪрд╛рдВрдЧрд▓рд╛ рд╣реЛрддрд╛. рдкрдг рдпрд╛ рддреАрди рдкрд░реНрдпрд╛рдпрд╛рдВрдкреИрдХреА рдХреЛрдгрддрд╛ рдкрд░реНрдпрд╛рдп рд╡рд╛рдкрд░рд╛рдпрдЪрд╛ рд╣реЗ рддреБрдордЪреНрдпрд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЖрд╣реЗ.
рд╕реНрддреНрд░реЛрдд: www.habr.com
