Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w7uCB-0000pd-36 for pgsql-performance@arkaria.postgresql.org; Wed, 01 Apr 2026 11:57:17 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w7uCA-00HI0i-2r for pgsql-performance@arkaria.postgresql.org; Wed, 01 Apr 2026 11:57:15 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w7uCA-00HI0a-0v for pgsql-performance@lists.postgresql.org; Wed, 01 Apr 2026 11:57:14 +0000 Received: from mail-ed1-x535.google.com ([2a00:1450:4864:20::535]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w7uC7-000000000Vg-1uFQ for pgsql-performance@lists.postgresql.org; Wed, 01 Apr 2026 11:57:14 +0000 Received: by mail-ed1-x535.google.com with SMTP id 4fb4d7f45d1cf-66bf6aa4858so5632815a12.2 for ; Wed, 01 Apr 2026 04:57:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1775044625; cv=none; d=google.com; s=arc-20240605; b=DK9MabDgOA5tA/oUGwxqfbWNXvNstIrrAMYyl89zm9j1PPVAXEpinNsq+zpPepoLJO NLlmHRcZx2GKC4Yg5NLDpXK5HA0m0ZHHlNe66DG1oFxnNvceW2i+h5fVM6uiH/ca0646 uPT0ioXRTjKCM2CUqA77iDz3YaTQQf/cKQT4lUHmFrKepQvcuIqhoVY7hUxKbVII05kq U5eY/PNy3hPvFWF2t+Z59iPS2n1Ssn1cFesrywB6V7xyqrP0FZpwHpEktiUdA3v++e6N bzG/XYuBhmduGuFMiTAOi/Fjf4TF78U6myozz+qDQVZtOPi+K6rYyrxFtXpL9fhw5pmT p5Xw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=Qhm0uvwGf9pfwu3uDwQGxYt3NxOtb3PkZ+z1AbdCjCc=; fh=z/JQ2tSXVGoYKKvtD/yyy3g3xqdpsR82Ngoo7GcsvL4=; b=CX2kki4N6LFPAARobR2VBn+PJRhkrQhhAnUEgFuJE66H9aNooZDJOo4wAUQId/eazV VxNap70u3B1VOrnQSLYROQxJ4ueW1+GB9vFXIzbm8FvS0p/e2b/d9jd8EUB46rD+9nrv O+doUOboaYhZj2MdgiWOgYrZwsuol+Slig0HR10ByimxB9JM3ZmqpAtDepBYeTf3qXjs yJlBGkQqPB7FMxbrpFErgrdwcaCEhHLCdMzUvXJHmH+EL+sJkOM06xqPOdNd9WnsdkMx spXs0pgSj+tDWnGyrnu9yCRfhzErGvU+aSDL0GRgBdRXKpXteaWDTbYH/WGOEmoYV0/7 g7UA==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ninehq.com; s=google; t=1775044625; x=1775649425; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=Qhm0uvwGf9pfwu3uDwQGxYt3NxOtb3PkZ+z1AbdCjCc=; b=uYpaw//Ez+SQZj9m4KSL4ToNoj8It7g8uh+6Bp/RV0TnvO1/gn5+zQch7Ww8R8K6mX X4qi3qlIzaWK0uX4N310+3P/RyHniZewPdJvx9eAQsw+Ie4FYZDUOIOLdjdTHIS9jAXn 4vcfHgyt7dnnY551iaFeePXYfnu7ex+fKwT5E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775044625; x=1775649425; h=to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Qhm0uvwGf9pfwu3uDwQGxYt3NxOtb3PkZ+z1AbdCjCc=; b=gp1t8QHz+ooAYD8bjuSrwPBh4bDLpWpsIFZinFg7Pyz6AXv+RUMNnDbSOQkXmUlcdt A7D+4DT2qZBI1GutcqkjZWjM9Gikdm2+++Q+oOK0zmboRWgVrbhTB4ziYcc/6CEaVPsr 8WwvBDJ/c63jk5O8n0bi3WqeIMI8+d3rlHaBTJ3uAL49IgjeXTDZm20+duxdyamIIzf9 JSon+ZM5Hj1kJ1v6l5BS0E3I6DRpNBP7dcsvWWvSeC5qpCLSEGn0135je0BBS88kj7v3 XLNi/KlRoxvTBR7fVH0apSZT1SBwHhDCcB8pgEGAb1hv1GZcvmRiE/vZn2UUDDsbvowZ LoxA== X-Gm-Message-State: AOJu0YwyjrSsYjmIkGzRiE2rdy+P5oV5/IcklTn8NdkP7Lw2+Bm5hCXr WbEo4WTbEJw5NKUVDPaTSKmctcZjklyinHoua8KWQ9VrUoBg88SYBEYEae5K0t9BkN2Rj+OeuJy xGnzaFZQKOkIpOoM66028sLE3soQqZx0bX9/GO4qyXRsrRyY/UKZ4GolQug== X-Gm-Gg: ATEYQzz9TAjctpwcScB4/FITR0/orWMVh+23At+yD+31MsfoMGCurzcrSI6Pta0HJBU 5DOaEY2T+x+LPH5vxeqImpJapUBOjX2K37q85HaLYsl4H6dthwfAjUI9Ge5t18ZCUqnPrf8g+h8 QiNo+K1StFZJ4dTdEOy/S6j2KWerR50I/mz1Kq2W6GI+TRS2TwUKy09IooDUIgL9NsVx/EzCWGW 2gvY1sS1wBXRkyG5qOlRbTm44TNRMpwW2LtlYbcHXcTB+BHA0MvPcmc7ahdoRrgLPvfip/F6hSj 4XLMVw== X-Received: by 2002:a17:906:6d17:b0:b97:bc3e:6143 with SMTP id a640c23a62f3a-b9c137ba38dmr190532266b.6.1775044624881; Wed, 01 Apr 2026 04:57:04 -0700 (PDT) MIME-Version: 1.0 From: =?UTF-8?Q?C=C3=A1ndido_Antonio_Mart=C3=ADnez_Descalzo?= Date: Wed, 1 Apr 2026 13:56:52 +0200 X-Gm-Features: AQROBzDlsYQ4s2M_kOBOjmIXFYcq6lQED3gLzWjXNedSFk4ZDjDCjTlapNG2IEE Message-ID: Subject: Potential partition pruning regression on PostgreSQL 18 To: pgsql-performance@lists.postgresql.org Content-Type: multipart/alternative; boundary="00000000000053aab3064e64c8ed" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000053aab3064e64c8ed Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi all, We noticed that one of our queries unexpectedly stopped applying partition pruning on PG18, although it applies it on PG16 and PG17. The issue has been replicated on Linux and macOS. Failing to apply partition pruning significantly impacts the performance of these queries. We recreated the issue using a simplified schema and query. Details on the schema, query and resulting plans in PG17 and PG18 are provided below. Some changes in the query restore partition pruning in PG18, specifically: - Replacing the view and date condition used with a sub-query or CTE with the same condition restores partition pruning (updated query and pl= an provided further below) - Keeping the view and using a single "group by" instead of multiple grouping sets restores partition pruning (updated query and plan provide= d further below) Does anybody know if there is a documented behaviour change in PG18 that could explain this or if this is a known issue? Many thanks, C=C3=A1ndido Mart=C3=ADnez ninehq This is the schema used: create table entity ( id integer primary key, name varchar(255) unique not null ); insert into entity (id, name) select i, 'Entity ' || i from generate_series(1, 1000, 1) g(i); create table entity_tags ( entity_id integer not null references entity(id), from_day date not null, to_day date not null, tag_1 text not null, tag_2 text not null, primary key (entity_id, from_day) ); insert into entity_tags select id, '2025-01-01'::date, '9999-12-31'::date, 'Tag 1-' || random(1,50), 'Tag 2-' || random(1, 10) from entity where id % 3 =3D 0; insert into entity_tags select id, '2025-01-01'::date, '2026-01-31'::date, 'Tag 1-' || random(1,50), 'Tag 2-' || random(1, 10) from entity where id % 3 =3D 1; insert into entity_tags select id, '2026-02-01'::date, '9999-12-31'::date, 'Tag 1-' || random(1,50), 'Tag 2-' || random(1, 10) from entity where id % 3 =3D 1; insert into entity_tags select id, '2025-01-01'::date, '2026-02-28'::date, 'Tag 1-' || random(1,50), 'Tag 2-' || random(1, 10) from entity where id % 3 =3D 2; insert into entity_tags select id, '2026-03-01'::date, '9999-12-31'::date, 'Tag 1-' || random(1,50), 'Tag 2-' || random(1, 10) from entity where id % 3 =3D 2; create table monthly_data ( month date not null, external_ref text not null, entity_id integer not null references entity(id), duration integer not null, counter integer not null, amount integer not null ) partition by RANGE (month); create index on monthly_data (external_ref); create index on monthly_data (entity_id); create view monthly_data_view as select * from monthly_data; create table monthly_data_202601 partition of monthly_data for values from = ( '2026-01-01') to ('2026-01-31'); create table monthly_data_202602 partition of monthly_data for values from = ( '2026-02-01') to ('2026-02-28'); create table monthly_data_202603 partition of monthly_data for values from = ( '2026-03-01') to ('2026-03-31'); insert into monthly_data with m as ( select d::date as month from generate_series('2026-01-01'::date, '2026-03-3= 1 '::date, '1 month') g(d) ) select m.month, 'ext-' || random(1, 50000), random(1, 1000), random(1, 1000= ), random(1, 1000), random(1, 100) from generate_series(1, 3000000, 1) g(i), m; analyze entity, entity_tags, monthly_data; And this is the query: select m.external_ref, t.tag_1, t.tag_2, sum(m.duration) as duration, sum(m.counter) as counter, sum(m.amount) as amount from monthly_data_view m join entity_tags t on m.entity_id =3D t.entity_id and m.month between t.from_day and t.to_day where m.month between '2026-02-01'::date and '2026-02-28'::date group by m.external_ref, grouping sets ((), t.tag_1, t.tag_2); *PostgreSQL 17 Plan:* GroupAggregate (cost=3D94584.40..253820.84 rows=3D1105572 width=3D49) (act= ual time=3D642.913..2291.658 rows=3D2271176 loops=3D1) Output: monthly_data.external_ref, t.tag_1, t.tag_2, sum(monthly_data.duration), sum(monthly_data.counter), sum(monthly_data.amount) Group Key: monthly_data.external_ref, t.tag_1 Group Key: monthly_data.external_ref Sort Key: monthly_data.external_ref, t.tag_2 Group Key: monthly_data.external_ref, t.tag_2 Buffers: shared hit=3D32066 read=3D13, temp read=3D36690 written=3D36703 I/O Timings: shared read=3D0.697, temp read=3D32.232 write=3D197.328 -> Gather Merge (cost=3D94584.40..159286.08 rows=3D555539 width=3D37) (= actual time=3D642.904..977.809 rows=3D3000000 loops=3D1) Output: monthly_data.external_ref, t.tag_1, t.tag_2, monthly_data.duration, monthly_data.counter, monthly_data.amount Workers Planned: 2 Workers Launched: 2 Buffers: shared hit=3D32066 read=3D13, temp read=3D18345 written=3D= 18351 I/O Timings: shared read=3D0.697, temp read=3D18.407 write=3D130.46= 1 -> Sort (cost=3D93584.38..94163.07 rows=3D231475 width=3D37) (act= ual time=3D622.100..709.953 rows=3D1000000 loops=3D3) Output: monthly_data.external_ref, t.tag_1, t.tag_2, monthly_data.duration, monthly_data.counter, monthly_data.amount Sort Key: monthly_data.external_ref, t.tag_1 Sort Method: external merge Disk: 52096kB Buffers: shared hit=3D32066 read=3D13, temp read=3D18345 written=3D18351 I/O Timings: shared read=3D0.697, temp read=3D18.407 write=3D= 130.461 Worker 0: actual time=3D614.585..706.233 rows=3D976888 loops= =3D1 Sort Method: external merge Disk: 47792kB Buffers: shared hit=3D10526, temp read=3D5974 written=3D597= 6 I/O Timings: temp read=3D6.759 write=3D49.156 Worker 1: actual time=3D609.153..697.519 rows=3D958096 loops= =3D1 Sort Method: external merge Disk: 46872kB Buffers: shared hit=3D10388, temp read=3D5859 written=3D586= 1 I/O Timings: temp read=3D5.899 write=3D43.593 -> Nested Loop (cost=3D0.29..72959.38 rows=3D231475 width= =3D37) (actual time=3D0.139..248.122 rows=3D1000000 loops=3D3) Output: monthly_data.external_ref, t.tag_1, t.tag_2, monthly_data.duration, monthly_data.counter, monthly_data.amount Buffers: shared hit=3D32050 read=3D13 I/O Timings: shared read=3D0.697 Worker 0: actual time=3D0.061..243.302 rows=3D976888 loops=3D1 Buffers: shared hit=3D10518 Worker 1: actual time=3D0.058..246.889 rows=3D958096 loops=3D1 Buffers: shared hit=3D10380 -> Parallel Seq Scan on public.monthly_data_202602 monthly_data (cost=3D0.00..40809.00 rows=3D1250000 width=3D29) (actual time=3D0.014..64.695 rows=3D1000000 loops=3D3) Output: monthly_data.external_ref, monthly_data.duration, monthly_data.counter, monthly_data.amount, monthly_data.entity_id, monthly_data.month Filter: ((monthly_data.month >=3D '2026-02-01'::date) AND (monthly_data.month <=3D '2026-02-28'::date)) Buffers: shared hit=3D22059 Worker 0: actual time=3D0.017..64.085 rows=3D976= 888 loops=3D1 Buffers: shared hit=3D7183 Worker 1: actual time=3D0.018..67.602 rows=3D958= 096 loops=3D1 Buffers: shared hit=3D7045 -> Memoize (cost=3D0.29..0.31 rows=3D1 width=3D28) (a= ctual time=3D0.000..0.000 rows=3D1 loops=3D3000000) Output: t.tag_1, t.tag_2, t.entity_id, t.from_day, t.to_day Cache Key: monthly_data.month, monthly_data.entity_id Cache Mode: binary Hits: 1064016 Misses: 1000 Evictions: 0 Overflows: 0 Memory Usage: 133kB Buffers: shared hit=3D9991 read=3D13 I/O Timings: shared read=3D0.697 Worker 0: actual time=3D0.000..0.000 rows=3D1 loops=3D976888 Hits: 975888 Misses: 1000 Evictions: 0 Overflows: 0 Memory Usage: 133kB Buffers: shared hit=3D3335 Worker 1: actual time=3D0.000..0.000 rows=3D1 loops=3D958096 Hits: 957096 Misses: 1000 Evictions: 0 Overflows: 0 Memory Usage: 133kB Buffers: shared hit=3D3335 -> Index Scan using entity_tags_pkey on public.entity_tags t (cost=3D0.28..0.30 rows=3D1 width=3D28) (actual time=3D0.002..0.002 rows=3D1 loops=3D3000) Output: t.tag_1, t.tag_2, t.entity_id, t.from_day, t.to_day Index Cond: ((t.entity_id =3D monthly_data.entity_id) AND (t.from_day <=3D monthly_data.month)) Filter: (monthly_data.month <=3D t.to_day) Rows Removed by Filter: 0 Buffers: shared hit=3D9991 read=3D13 I/O Timings: shared read=3D0.697 Worker 0: actual time=3D0.002..0.002 rows= =3D1 loops=3D1000 Buffers: shared hit=3D3335 Worker 1: actual time=3D0.001..0.002 rows= =3D1 loops=3D1000 Buffers: shared hit=3D3335 *PostgreSQL 18 plan (no partition pruning):* HashAggregate (cost=3D229746.36..242370.87 rows=3D12200 width=3D72) (actua= l time=3D1621.794..2508.533 rows=3D2262361.00 loops=3D1) Output: monthly_data.external_ref, t.tag_1, t.tag_2, sum(monthly_data.duration), sum(monthly_data.counter), sum(monthly_data.amount) Hash Key: monthly_data.external_ref, t.tag_1 Hash Key: monthly_data.external_ref Hash Key: monthly_data.external_ref, t.tag_2 Batches: 13 Memory Usage: 54433kB Disk Usage: 250536kB Buffers: shared hit=3D66216, temp read=3D31017 written=3D58146 I/O Timings: temp read=3D29.524 write=3D118.672 -> Gather (cost=3D1050.51..222800.52 rows=3D555667 width=3D60) (actual time=3D93.721..192.443 rows=3D3000000.00 loops=3D1) Output: monthly_data.external_ref, t.tag_1, t.tag_2, monthly_data.duration, monthly_data.counter, monthly_data.amount Workers Planned: 2 Workers Launched: 2 Buffers: shared hit=3D66216 -> Hash Join (cost=3D50.51..166233.82 rows=3D231528 width=3D60) (= actual time=3D63.866..320.145 rows=3D1000000.00 loops=3D3) Output: monthly_data.external_ref, t.tag_1, t.tag_2, monthly_data.duration, monthly_data.counter, monthly_data.amount Hash Cond: (monthly_data.entity_id =3D t.entity_id) Join Filter: ((monthly_data.month >=3D t.from_day) AND (monthly_data.month <=3D t.to_day)) Rows Removed by Join Filter: 667154 Buffers: shared hit=3D66216 Worker 0: actual time=3D0.852..768.416 rows=3D2995648.00 loo= ps=3D1 Buffers: shared hit=3D22040 Worker 1: actual time=3D97.229..97.847 rows=3D2176.00 loops= =3D1 Buffers: shared hit=3D22088 -> Parallel Append (cost=3D0.00..128677.01 rows=3D1250002 width=3D52) (actual time=3D63.442..158.419 rows=3D1000000.00 loops=3D3) Buffers: shared hit=3D66177 Worker 0: actual time=3D0.032..284.520 rows=3D2995648.= 00 loops=3D1 Buffers: shared hit=3D22027 Worker 1: actual time=3D96.963..97.184 rows=3D2176.00 loops=3D1 Buffers: shared hit=3D22075 -> Parallel Seq Scan on public.monthly_data_202601 monthly_data_1 (cost=3D0.00..40809.00 rows=3D1 width=3D52) (actual time=3D96.957..96.957 rows=3D0.00 loops=3D1) Output: monthly_data_1.external_ref, monthly_data_1.duration, monthly_data_1.counter, monthly_data_1.amount, monthly_data_1.entity_id, monthly_data_1.month Filter: ((monthly_data_1.month >=3D '2026-02-01'::date) AND (monthly_data_1.month <=3D '2026-02-28'::date)) Rows Removed by Filter: 3000000 Buffers: shared hit=3D22059 Worker 1: actual time=3D96.957..96.957 rows=3D0.= 00 loops=3D1 Buffers: shared hit=3D22059 -> Parallel Seq Scan on public.monthly_data_202602 monthly_data_2 (cost=3D0.00..40809.00 rows=3D1250000 width=3D52) (actual time=3D0.013..62.957 rows=3D1000000.00 loops=3D3) Output: monthly_data_2.external_ref, monthly_data_2.duration, monthly_data_2.counter, monthly_data_2.amount, monthly_data_2.entity_id, monthly_data_2.month Filter: ((monthly_data_2.month >=3D '2026-02-01'::date) AND (monthly_data_2.month <=3D '2026-02-28'::date)) Buffers: shared hit=3D22059 Worker 0: actual time=3D0.032..188.573 rows=3D2995648.00 loops=3D1 Buffers: shared hit=3D22027 Worker 1: actual time=3D0.005..0.153 rows=3D2176= .00 loops=3D1 Buffers: shared hit=3D16 -> Parallel Seq Scan on public.monthly_data_202603 monthly_data_3 (cost=3D0.00..40809.00 rows=3D1 width=3D52) (actual time=3D93.328..93.328 rows=3D0.00 loops=3D1) Output: monthly_data_3.external_ref, monthly_data_3.duration, monthly_data_3.counter, monthly_data_3.amount, monthly_data_3.entity_id, monthly_data_3.month Filter: ((monthly_data_3.month >=3D '2026-02-01'::date) AND (monthly_data_3.month <=3D '2026-02-28'::date)) Rows Removed by Filter: 3000000 Buffers: shared hit=3D22059 -> Hash (cost=3D29.67..29.67 rows=3D1667 width=3D28) (actua= l time=3D0.412..0.412 rows=3D1667.00 loops=3D3) Output: t.tag_1, t.tag_2, t.entity_id, t.from_day, t.to_day Buckets: 2048 Batches: 1 Memory Usage: 120kB Buffers: shared hit=3D39 Worker 0: actual time=3D0.807..0.807 rows=3D1667.00 lo= ops=3D1 Buffers: shared hit=3D13 Worker 1: actual time=3D0.248..0.248 rows=3D1667.00 lo= ops=3D1 Buffers: shared hit=3D13 -> Seq Scan on public.entity_tags t (cost=3D0.00..29.= 67 rows=3D1667 width=3D28) (actual time=3D0.058..0.222 rows=3D1667.00 loops=3D= 3) Output: t.tag_1, t.tag_2, t.entity_id, t.from_day, t.to_day Buffers: shared hit=3D39 Worker 0: actual time=3D0.104..0.435 rows=3D1667= .00 loops=3D1 Buffers: shared hit=3D13 Worker 1: actual time=3D0.058..0.137 rows=3D1667= .00 loops=3D1 Buffers: shared hit=3D13 *On PG18, replacing the monthly_data_view and month condition with a sub-query or CTE restores partition pruning:* with m as ( select * from monthly_data where month between '2026-02-01'::date and '2026-02-28'::date ) select m.external_ref, t.tag_1, t.tag_2, sum(m.duration) as duration, sum(m.counter) as counter, sum(m.amount) as amount from m join entity_tags t on m.entity_id =3D t.entity_id and m.month between t.from_day and t.to_day group by m.external_ref, grouping sets ((), t.tag_1, t.tag_2); HashAggregate (cost=3D141878.30..154502.80 rows=3D12200 width=3D72) (actua= l time=3D1583.549..2502.394 rows=3D2262361.00 loops=3D1) Output: monthly_data.external_ref, t.tag_1, t.tag_2, sum(monthly_data.duration), sum(monthly_data.counter), sum(monthly_data.amount) Hash Key: monthly_data.external_ref, t.tag_1 Hash Key: monthly_data.external_ref Hash Key: monthly_data.external_ref, t.tag_2 Batches: 13 Memory Usage: 54433kB Disk Usage: 250552kB Buffers: shared hit=3D22098, temp read=3D31016 written=3D58135 I/O Timings: temp read=3D27.912 write=3D116.172 -> Gather (cost=3D1050.51..134932.46 rows=3D555667 width=3D60) (actual time=3D1.314..105.099 rows=3D3000000.00 loops=3D1) Output: monthly_data.external_ref, t.tag_1, t.tag_2, monthly_data.duration, monthly_data.counter, monthly_data.amount Workers Planned: 2 Workers Launched: 2 Buffers: shared hit=3D22098 -> Hash Join (cost=3D50.51..78365.76 rows=3D231528 width=3D60) (a= ctual time=3D0.783..239.677 rows=3D1000000.00 loops=3D3) Output: monthly_data.external_ref, t.tag_1, t.tag_2, monthly_data.duration, monthly_data.counter, monthly_data.amount Hash Cond: (monthly_data.entity_id =3D t.entity_id) Join Filter: ((monthly_data.month >=3D t.from_day) AND (monthly_data.month <=3D t.to_day)) Rows Removed by Join Filter: 667154 Buffers: shared hit=3D22098 Worker 0: actual time=3D0.726..698.352 rows=3D2969536.00 loo= ps=3D1 Buffers: shared hit=3D21848 Worker 1: actual time=3D0.653..16.148 rows=3D26112.00 loops= =3D1 Buffers: shared hit=3D205 -> Parallel Seq Scan on public.monthly_data_202602 monthly_data (cost=3D0.00..40809.00 rows=3D1250000 width=3D52) (actual time=3D0.022..68.714 rows=3D1000000.00 loops=3D3) Output: monthly_data.external_ref, monthly_data.duration, monthly_data.counter, monthly_data.amount, monthly_data.entity_id, monthly_data.month Filter: ((monthly_data.month >=3D '2026-02-01'::date) A= ND (monthly_data.month <=3D '2026-02-28'::date)) Buffers: shared hit=3D22059 Worker 0: actual time=3D0.030..199.783 rows=3D2969536.= 00 loops=3D1 Buffers: shared hit=3D21835 Worker 1: actual time=3D0.023..5.233 rows=3D26112.00 loops=3D1 Buffers: shared hit=3D192 -> Hash (cost=3D29.67..29.67 rows=3D1667 width=3D28) (actua= l time=3D0.749..0.749 rows=3D1667.00 loops=3D3) Output: t.tag_1, t.tag_2, t.entity_id, t.from_day, t.to_day Buckets: 2048 Batches: 1 Memory Usage: 120kB Buffers: shared hit=3D39 Worker 0: actual time=3D0.679..0.679 rows=3D1667.00 lo= ops=3D1 Buffers: shared hit=3D13 Worker 1: actual time=3D0.621..0.622 rows=3D1667.00 lo= ops=3D1 Buffers: shared hit=3D13 -> Seq Scan on public.entity_tags t (cost=3D0.00..29.= 67 rows=3D1667 width=3D28) (actual time=3D0.058..0.388 rows=3D1667.00 loops=3D= 3) Output: t.tag_1, t.tag_2, t.entity_id, t.from_day, t.to_day Buffers: shared hit=3D39 Worker 0: actual time=3D0.092..0.420 rows=3D1667= .00 loops=3D1 Buffers: shared hit=3D13 Worker 1: actual time=3D0.072..0.321 rows=3D1667= .00 loops=3D1 Buffers: shared hit=3D13 *On PG18 pruning is also restored keeping the view but performing a single "group by" instead of multiple grouping sets:* select t.tag_1, sum(m.duration) as duration, sum(m.counter) as counter, sum= ( m.amount) as amount from monthly_data_view m join entity_tags t on m.entity_id =3D t.entity_id and m.month between t.fro= m_day and t.to_day where m.month between '2026-02-01'::date and '2026-02-28'::date group by t.tag_1; Finalize GroupAggregate (cost=3D81682.97..81698.65 rows=3D50 width=3D32) (= actual time=3D356.116..358.029 rows=3D50.00 loops=3D1) Output: t.tag_1, sum(monthly_data.duration), sum(monthly_data.counter), sum(monthly_data.amount) Group Key: t.tag_1 Buffers: shared hit=3D22114 -> Gather Merge (cost=3D81682.97..81696.95 rows=3D120 width=3D32) (actu= al time=3D356.111..358.009 rows=3D150.00 loops=3D1) Output: t.tag_1, (PARTIAL sum(monthly_data.duration)), (PARTIAL sum(monthly_data.counter)), (PARTIAL sum(monthly_data.amount)) Workers Planned: 2 Workers Launched: 2 Buffers: shared hit=3D22114 -> Sort (cost=3D80682.95..80683.07 rows=3D50 width=3D32) (actual time=3D349.568..349.570 rows=3D50.00 loops=3D3) Output: t.tag_1, (PARTIAL sum(monthly_data.duration)), (PARTIAL sum(monthly_data.counter)), (PARTIAL sum(monthly_data.amount)) Sort Key: t.tag_1 Sort Method: quicksort Memory: 27kB Buffers: shared hit=3D22114 Worker 0: actual time=3D346.658..346.660 rows=3D50.00 loops= =3D1 Sort Method: quicksort Memory: 27kB Buffers: shared hit=3D7385 Worker 1: actual time=3D346.663..346.665 rows=3D50.00 loops= =3D1 Sort Method: quicksort Memory: 27kB Buffers: shared hit=3D7235 -> Partial HashAggregate (cost=3D80681.04..80681.54 rows=3D= 50 width=3D32) (actual time=3D349.530..349.533 rows=3D50.00 loops=3D3) Output: t.tag_1, PARTIAL sum(monthly_data.duration), PARTIAL sum(monthly_data.counter), PARTIAL sum(monthly_data.amount) Group Key: t.tag_1 Batches: 1 Memory Usage: 32kB Buffers: shared hit=3D22098 Worker 0: actual time=3D346.608..346.611 rows=3D50.00 loops=3D1 Batches: 1 Memory Usage: 32kB Buffers: shared hit=3D7377 Worker 1: actual time=3D346.615..346.618 rows=3D50.00 loops=3D1 Batches: 1 Memory Usage: 32kB Buffers: shared hit=3D7227 -> Hash Join (cost=3D50.51..78365.76 rows=3D231528 width=3D20) (actual time=3D0.936..260.236 rows=3D1000000.00 loops=3D3) Output: t.tag_1, monthly_data.duration, monthly_data.counter, monthly_data.amount Hash Cond: (monthly_data.entity_id =3D t.entity_i= d) Join Filter: ((monthly_data.month >=3D t.from_day= ) AND (monthly_data.month <=3D t.to_day)) Rows Removed by Join Filter: 667154 Buffers: shared hit=3D22098 Worker 0: actual time=3D1.031..261.125 rows=3D1001480.00 loops=3D1 Buffers: shared hit=3D7377 Worker 1: actual time=3D0.947..259.326 rows=3D981104.00 loops=3D1 Buffers: shared hit=3D7227 -> Parallel Seq Scan on public.monthly_data_202602 monthly_data (cost=3D0.00..40809.00 rows=3D1250= 000 width=3D20) (actual time=3D0.027..79.622 rows=3D1000000.00 loops=3D3) Output: monthly_data.duration, monthly_data.counter, monthly_data.amount, monthly_data.entity_id, monthly_data.month Filter: ((monthly_data.month >=3D '2026-02-01'::date) AND (monthly_data.month <=3D '2026-02-28'::date)) Buffers: shared hit=3D22059 Worker 0: actual time=3D0.030..80.173 rows=3D1001480.00 loops=3D1 Buffers: shared hit=3D7364 Worker 1: actual time=3D0.031..82.531 rows=3D981104.00 loops=3D1 Buffers: shared hit=3D7214 -> Hash (cost=3D29.67..29.67 rows=3D1667 width= =3D20) (actual time=3D0.895..0.895 rows=3D1667.00 loops=3D3) Output: t.tag_1, t.entity_id, t.from_day, t.to_day Buckets: 2048 Batches: 1 Memory Usage: 106kB Buffers: shared hit=3D39 Worker 0: actual time=3D0.983..0.983 rows=3D1667.00 loops=3D1 Buffers: shared hit=3D13 Worker 1: actual time=3D0.898..0.898 rows=3D1667.00 loops=3D1 Buffers: shared hit=3D13 -> Seq Scan on public.entity_tags t (cost=3D0.00..29.67 rows=3D1667 width=3D20) (actual time=3D0.081..0.542 rows=3D1667.00 loops=3D3) Output: t.tag_1, t.entity_id, t.from_day, t.to_day Buffers: shared hit=3D39 Worker 0: actual time=3D0.118..0.540 rows=3D1667.00 loops=3D1 Buffers: shared hit=3D13 Worker 1: actual time=3D0.117..0.483 rows=3D1667.00 loops=3D1 Buffers: shared hit=3D13 --00000000000053aab3064e64c8ed Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi all,

We noticed tha= t one of our queries unexpectedly stopped applying partition pruning on PG1= 8, although it applies it on PG16 and PG17. The issue has been replicated o= n Linux and macOS.

Failing to apply partition prun= ing significantly impacts the performance of these queries.

<= /div>
We recreated the issue using a simplified schema and query. Detai= ls on the schema, query and resulting plans in PG17 and PG18 are provided b= elow. Some changes in the query restore partition pruning in PG18, specific= ally:
  • Replacing the view and date condition used with a s= ub-query or CTE=C2=A0 with the same condition restores partition pruning (u= pdated query and plan provided further below)
  • Keeping the view and = using a single "group by" instead of multiple grouping sets resto= res partition pruning (updated query and plan provided further below)
  • <= /ul>

Does anybody know if there is a documented be= haviour change in PG18 that could explain this or if this is a known issue?=

Many thanks,

C=C3= =A1ndido Mart=C3=ADnez
ninehq

This= is the schema used:
create table entity (
id integer primary key,
= name varchar(255)= unique not null
);

insert into
entity (id, = name)
select i= , 'Entity ' || i from generate_series(1, 1000,= 1) g(i);

create table
entity_tags (
entity_id integer not null refe= rences entity(id),
from_day date not null,
to_day date not null,
tag_1 text not = null,
tag_2 text not null
,
primary key (entity_id, from_day
)
);

insert into entity_tags
select id, = '2025-01-01'::date= , '9999-12-31'::date, 'Tag 1-' || random(1,50), 'Tag 2-' || random(1, 10)
from entity where id % 3 =3D 0;

insert into <= /span>entity_tags
select i= d, '2025-01-01'
::date, '2026-01-31'::date, 'Tag 1-= ' || random(1,50), 'Tag 2-' || random(1, 10)
from entity where id = % 3 =3D 1;

i= nsert into entity_tags
select
id, '2026-02-01=
'::date, '9= 999-12-31'::date, 'Tag 1-' || random(1,50), 'Tag 2-' || random(1, <= span style=3D"color:rgb(23,80,235)">10)
from entity where
id % 3 =3D 1;

insert into entity_tagsselect id, '= 2025-01-01'::date, '2026-02-28':= :date, 'Tag 1-' || random(1,50), 'Tag 2-' || random(1= , 10)
from entity where id % 3 = =3D 2;

insert into enti= ty_tags
select id, '2026-03-01'= ::date, '9999-12-31= 9;::date, 'Tag 1-' || random(1,50), 'Tag 2-&#= 39; || random(1, 10)
from
entity where id % 3 =3D 2;

create table monthly_data (
m= onth date not null,
= external_ref text not null,
entity_id integer n= ot null references entity(id
),
duration integ= er not null,
counter integer not null,
amount
integer not null
) partition by RANGE (month);
create index on monthly_data (external_ref);
crea= te index on monthly_data (entity_id
);
create view monthly_data_view as select * from mon=
thly_data;
create table= monthly_data_202601 partition of monthly_data for values f= rom ('2026-01-01'= ) to ('2026-01-31');
create table monthly_data_20260= 2 partition of monthly_data for values from ('2026-0= 2-01') to ('2026-02-28');
create table mo= nthly_data_202603 partition of <= /span>monthly_data for values from ('2026-03-01') to ('2026-03-31');
=
insert into monthly_data
with m as (
sele= ct d::date as month from generate_series('2026-01-01'::date, '2026-03-31'::date, '1 month') g(d)<= br>)
select m.month, 'ext-'
|| random(1, 50000), random(1, 1000), random(1, 1000), random(1, = 1000), random<= /span>(1, 100)
from generate_series(1, 3000000, 1) g(i), m;

analyze entity, entity_tags, monthly_data;
And this is the query:
<= div>
select =
m.external_ref, t.tag_1, t.tag_2, sum(m.duration)=
 as duration, sum(m.counter) as counter, sum(m.amount) as amount<=
br>from monthly_data_view=
 m
join entity_tags t on
m.entity_id =3D t.= entity_id and m.month = between t.from_day and t.to_day
where
m.month between '2026-02-01':= :date and '2026-02-28&= #39;::date
group by m= .external_ref, grouping sets ((), t.tag_1, t.tag_2);
PostgreSQL 17 Plan:
GroupAggregate =C2=A0(cost=3D94584.40..253820.84 rows=3D1105572 width= =3D49) (actual time=3D642.913..2291.658 rows=3D2271176 loops=3D1)
=C2=A0= Output: monthly_data.external_ref, t.tag_1, t.tag_2, sum(monthly_data.dura= tion), sum(monthly_data.counter), sum(monthly_data.amount)
=C2=A0 Group = Key: monthly_data.external_ref, t.tag_1
=C2=A0 Group Key: monthly_data.e= xternal_ref
=C2=A0 Sort Key: monthly_data.external_ref, t.tag_2
=C2= =A0 =C2=A0 Group Key: monthly_data.external_ref, t.tag_2
=C2=A0 Buffers:= shared hit=3D32066 read=3D13, temp read=3D36690 written=3D36703
=C2=A0 = I/O Timings: shared read=3D0.697, temp read=3D32.232 write=3D197.328
=C2= =A0 -> =C2=A0Gather Merge =C2=A0(cost=3D94584.40..159286.08 rows=3D55553= 9 width=3D37) (actual time=3D642.904..977.809 rows=3D3000000 loops=3D1)
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: monthly_data.external_ref, t.tag_1, t.t= ag_2, monthly_data.duration, monthly_data.counter, monthly_data.amount
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 Workers Planned: 2
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 Workers Launched: 2
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit= =3D32066 read=3D13, temp read=3D18345 written=3D18351
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 I/O Timings: shared read=3D0.697, temp read=3D18.407 write=3D130= .461
=C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Sort =C2=A0(cost=3D93584.38= ..94163.07 rows=3D231475 width=3D37) (actual time=3D622.100..709.953 rows= =3D1000000 loops=3D3)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 O= utput: monthly_data.external_ref, t.tag_1, t.tag_2, monthly_data.duration, = monthly_data.counter, monthly_data.amount
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Sort Key: monthly_data.external_ref, t.tag_1
=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Sort Method: external merge =C2= =A0Disk: 52096kB
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffer= s: shared hit=3D32066 read=3D13, temp read=3D18345 written=3D18351
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 I/O Timings: shared read=3D0.= 697, temp read=3D18.407 write=3D130.461
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D614.585..706.233 rows=3D976= 888 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 So= rt Method: external merge =C2=A0Disk: 47792kB
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D10526, temp read=3D59= 74 written=3D5976
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 I/O Timings: temp read=3D6.759 write=3D49.156
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual time=3D609.153..697.519 = rows=3D958096 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 Sort Method: external merge =C2=A0Disk: 46872kB
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D10388, temp= read=3D5859 written=3D5861
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 I/O Timings: temp read=3D5.899 write=3D43.593
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Nested Loop =C2=A0(cost= =3D0.29..72959.38 rows=3D231475 width=3D37) (actual time=3D0.139..248.122 r= ows=3D1000000 loops=3D3)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 Output: monthly_data.external_ref, t.tag_1, t.tag_= 2, monthly_data.duration, monthly_data.counter, monthly_data.amount
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers:= shared hit=3D32050 read=3D13
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 I/O Timings: shared read=3D0.697
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2= =A0actual time=3D0.061..243.302 rows=3D976888 loops=3D1
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: sha= red hit=3D10518
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 Worker 1: =C2=A0actual time=3D0.058..246.889 rows=3D958096 lo= ops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 Buffers: shared hit=3D10380
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Parallel Seq Scan on = public.monthly_data_202602 monthly_data =C2=A0(cost=3D0.00..40809.00 rows= =3D1250000 width=3D29) (actual time=3D0.014..64.695 rows=3D1000000 loops=3D= 3)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 Output: monthly_data.external_ref, monthly_data.durat= ion, monthly_data.counter, monthly_data.amount, monthly_data.entity_id, mon= thly_data.month
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Filter: ((monthly_data.month >=3D = 9;2026-02-01'::date) AND (monthly_data.month <=3D '2026-02-28= 9;::date))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D22059
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 Worker 0: =C2=A0actual time=3D0.017..64.085 rows=3D976888 loops=3D1<= br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D7183
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 W= orker 1: =C2=A0actual time=3D0.018..67.602 rows=3D958096 loops=3D1
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D7045
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Memoize =C2=A0(co= st=3D0.29..0.31 rows=3D1 width=3D28) (actual time=3D0.000..0.000 rows=3D1 l= oops=3D3000000)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: t.tag_1, t.tag_2, t.entity_id, t= .from_day, t.to_day
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Cache Key: monthly_data.month, month= ly_data.entity_id
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Cache Mode: binary
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Hits: 1064016 =C2=A0Misses: 1000 =C2=A0Evictions: 0 =C2=A0Overflows: 0 = =C2=A0Memory Usage: 133kB
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D9991 re= ad=3D13
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 I/O Timings: shared read=3D0.697
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 Worker 0: =C2=A0actual time=3D0.000..0.000 rows=3D1 loops=3D976888=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 Hits: 975888 =C2=A0Misses: 1000 =C2=A0Evictions: 0= =C2=A0Overflows: 0 =C2=A0Memory Usage: 133kB
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 B= uffers: shared hit=3D3335
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual time= =3D0.000..0.000 rows=3D1 loops=3D958096
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Hits: 95= 7096 =C2=A0Misses: 1000 =C2=A0Evictions: 0 =C2=A0Overflows: 0 =C2=A0Memory = Usage: 133kB
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D3335
=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 -> =C2=A0Index Scan using entity_tags_pkey on public.entity_t= ags t =C2=A0(cost=3D0.28..0.30 rows=3D1 width=3D28) (actual time=3D0.002..0= .002 rows=3D1 loops=3D3000)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Outpu= t: t.tag_1, t.tag_2, t.entity_id, t.from_day, t.to_day
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Index Cond: ((t.entity_id =3D monthly_data.entity_id) = AND (t.from_day <=3D monthly_data.month))
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Filter: (monthly_data.month <=3D t.to_day)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 Rows Removed by Filter: 0
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 Buffers: shared hit=3D9991 read=3D13
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 I/O Timings: shared read=3D0.697
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D0.002..0.002 rows=3D1 lo= ops=3D1000
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared= hit=3D3335
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual= time=3D0.001..0.002 rows=3D1 loops=3D1000
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 Buffers: shared hit=3D3335


PostgreSQL 18 plan (no partiti= on pruning):
HashA= ggregate =C2=A0(cost=3D229746.36..242370.87 rows=3D12200 width=3D72) (actua= l time=3D1621.794..2508.533 rows=3D2262361.00 loops=3D1)
=C2=A0 Output: = monthly_data.external_ref, t.tag_1, t.tag_2, sum(monthly_data.duration), su= m(monthly_data.counter), sum(monthly_data.amount)
=C2=A0 Hash Key: month= ly_data.external_ref, t.tag_1
=C2=A0 Hash Key: monthly_data.external_ref=
=C2=A0 Hash Key: monthly_data.external_ref, t.tag_2
=C2=A0 Batches: = 13 =C2=A0Memory Usage: 54433kB =C2=A0Disk Usage: 250536kB
=C2=A0 Buffers= : shared hit=3D66216, temp read=3D31017 written=3D58146
=C2=A0 I/O Timin= gs: temp read=3D29.524 write=3D118.672
=C2=A0 -> =C2=A0Gather =C2=A0(= cost=3D1050.51..222800.52 rows=3D555667 width=3D60) (actual time=3D93.721..= 192.443 rows=3D3000000.00 loops=3D1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Output:= monthly_data.external_ref, t.tag_1, t.tag_2, monthly_data.duration, monthl= y_data.counter, monthly_data.amount
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Workers = Planned: 2
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Workers Launched: 2
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 Buffers: shared hit=3D66216
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 -> =C2=A0Hash Join =C2=A0(cost=3D50.51..166233.82 rows=3D231528 widt= h=3D60) (actual time=3D63.866..320.145 rows=3D1000000.00 loops=3D3)
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: monthly_data.external= _ref, t.tag_1, t.tag_2, monthly_data.duration, monthly_data.counter, monthl= y_data.amount
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Hash Cond= : (monthly_data.entity_id =3D t.entity_id)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Join Filter: ((monthly_data.month >=3D t.from_day) = AND (monthly_data.month <=3D t.to_day))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Rows Removed by Join Filter: 667154
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D66216
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D0.8= 52..768.416 rows=3D2995648.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D22040
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual time=3D97.229..97.84= 7 rows=3D2176.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Buffers: shared hit=3D22088
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 -> =C2=A0Parallel Append =C2=A0(cost=3D0.00..128677.01= rows=3D1250002 width=3D52) (actual time=3D63.442..158.419 rows=3D1000000.0= 0 loops=3D3)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Buffers: shared hit=3D66177
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D0.032.= .284.520 rows=3D2995648.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D22027
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worke= r 1: =C2=A0actual time=3D96.963..97.184 rows=3D2176.00 loops=3D1
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffe= rs: shared hit=3D22075
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Parallel Seq Scan on public.monthly_data_2= 02601 monthly_data_1 =C2=A0(cost=3D0.00..40809.00 rows=3D1 width=3D52) (act= ual time=3D96.957..96.957 rows=3D0.00 loops=3D1)
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Outpu= t: monthly_data_1.external_ref, monthly_data_1.duration, monthly_data_1.cou= nter, monthly_data_1.amount, monthly_data_1.entity_id, monthly_data_1.month=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Filter: ((monthly_data_1.month >=3D '2026-02-01= '::date) AND (monthly_data_1.month <=3D '2026-02-28'::date))=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Rows Removed by Filter: 3000000
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 B= uffers: shared hit=3D22059
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual time= =3D96.957..96.957 rows=3D0.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers:= shared hit=3D22059
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 -> =C2=A0Parallel Seq Scan on public.monthly_data_2026= 02 monthly_data_2 =C2=A0(cost=3D0.00..40809.00 rows=3D1250000 width=3D52) (= actual time=3D0.013..62.957 rows=3D1000000.00 loops=3D3)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Output: monthly_data_2.external_ref, monthly_data_2.duration, monthly_d= ata_2.counter, monthly_data_2.amount, monthly_data_2.entity_id, monthly_dat= a_2.month
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 Filter: ((monthly_data_2.month >=3D '20= 26-02-01'::date) AND (monthly_data_2.month <=3D '2026-02-28'= ::date))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D22059
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Worker 0: =C2=A0actual time=3D0.032..188.573 rows=3D2995648.00 loops=3D= 1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D22027
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Worker 1: =C2=A0actual time=3D0.005..0.153 rows=3D2176.00 loops=3D1
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D16
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Parallel Seq S= can on public.monthly_data_202603 monthly_data_3 =C2=A0(cost=3D0.00..40809.= 00 rows=3D1 width=3D52) (actual time=3D93.328..93.328 rows=3D0.00 loops=3D1= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Output: monthly_data_3.external_ref, monthly_data_3.du= ration, monthly_data_3.counter, monthly_data_3.amount, monthly_data_3.entit= y_id, monthly_data_3.month
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Filter: ((monthly_data_3.mont= h >=3D '2026-02-01'::date) AND (monthly_data_3.month <=3D = 9;2026-02-28'::date))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Rows Removed by Filter: 30000= 00
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D22059
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Hash =C2=A0(cost=3D29.67..29.67 row= s=3D1667 width=3D28) (actual time=3D0.412..0.412 rows=3D1667.00 loops=3D3)<= br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Ou= tput: t.tag_1, t.tag_2, t.entity_id, t.from_day, t.to_day
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buckets: 2048 =C2= =A0Batches: 1 =C2=A0Memory Usage: 120kB
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D39
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 0: = =C2=A0actual time=3D0.807..0.807 rows=3D1667.00 loops=3D1
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: sha= red hit=3D13
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Worker 1: =C2=A0actual time=3D0.248..0.248 rows=3D1667.00 loops= =3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Buffers: shared hit=3D13
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Seq Scan on public.entity_ta= gs t =C2=A0(cost=3D0.00..29.67 rows=3D1667 width=3D28) (actual time=3D0.058= ..0.222 rows=3D1667.00 loops=3D3)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: t.tag_1, t.tag= _2, t.entity_id, t.from_day, t.to_day
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hi= t=3D39
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D0.104..0.435 rows= =3D1667.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D13=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual time=3D0.058..0.137 rows=3D1667.00= loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D13
<= br>
On PG18, replacing the= monthly_data_view and month condition with a sub-query or CTE restores par= tition pruning:
with =
m as (
select * = from monthly_data where = month between '= 2026-02-01'::date and '2026-02-28'::date
)
select m.external_ref, t.tag_1= , t.tag_2, sum(m.duration) as duration, sum(m.counter) as counter, sum<= /span>(m.amount) as amount
from m
join ent= ity_tags t on m.entity_id =3D t.<= span style=3D"color:rgb(135,16,148)">entity_id
and m.month between t.from_day and t.to_day
group by m.external_ref, grouping sets ((), = t.tag_1, t.tag_2);
HashAggregate =C2=A0(c= ost=3D141878.30..154502.80 rows=3D12200 width=3D72) (actual time=3D1583.549= ..2502.394 rows=3D2262361.00 loops=3D1)
=C2=A0 Output: monthly_data.exte= rnal_ref, t.tag_1, t.tag_2, sum(monthly_data.duration), sum(monthly_data.co= unter), sum(monthly_data.amount)
=C2=A0 Hash Key: monthly_data.external_= ref, t.tag_1
=C2=A0 Hash Key: monthly_data.external_ref
=C2=A0 Hash K= ey: monthly_data.external_ref, t.tag_2
=C2=A0 Batches: 13 =C2=A0Memory U= sage: 54433kB =C2=A0Disk Usage: 250552kB
=C2=A0 Buffers: shared hit=3D22= 098, temp read=3D31016 written=3D58135
=C2=A0 I/O Timings: temp read=3D2= 7.912 write=3D116.172
=C2=A0 -> =C2=A0Gather =C2=A0(cost=3D1050.51..1= 34932.46 rows=3D555667 width=3D60) (actual time=3D1.314..105.099 rows=3D300= 0000.00 loops=3D1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: monthly_data.exte= rnal_ref, t.tag_1, t.tag_2, monthly_data.duration, monthly_data.counter, mo= nthly_data.amount
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Workers Planned: 2
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 Workers Launched: 2
=C2=A0 =C2=A0 =C2=A0 =C2=A0= Buffers: shared hit=3D22098
=C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Has= h Join =C2=A0(cost=3D50.51..78365.76 rows=3D231528 width=3D60) (actual time= =3D0.783..239.677 rows=3D1000000.00 loops=3D3)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 Output: monthly_data.external_ref, t.tag_1, t.tag_= 2, monthly_data.duration, monthly_data.counter, monthly_data.amount
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Hash Cond: (monthly_data.enti= ty_id =3D t.entity_id)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = Join Filter: ((monthly_data.month >=3D t.from_day) AND (monthly_data.mon= th <=3D t.to_day))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 R= ows Removed by Join Filter: 667154
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 Buffers: shared hit=3D22098
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D0.726..698.352 rows=3D29= 69536.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Buffers: shared hit=3D21848
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Worker 1: =C2=A0actual time=3D0.653..16.148 rows=3D26112.00 loop= s=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: s= hared hit=3D205
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> = =C2=A0Parallel Seq Scan on public.monthly_data_202602 monthly_data =C2=A0(c= ost=3D0.00..40809.00 rows=3D1250000 width=3D52) (actual time=3D0.022..68.71= 4 rows=3D1000000.00 loops=3D3)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: monthly_data.external_ref, monthly_dat= a.duration, monthly_data.counter, monthly_data.amount, monthly_data.entity_= id, monthly_data.month
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Filter: ((monthly_data.month >=3D '2026-02-01&#= 39;::date) AND (monthly_data.month <=3D '2026-02-28'::date))
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffe= rs: shared hit=3D22059
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D0.030..199.783 rows=3D29= 69536.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D21835
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual= time=3D0.023..5.233 rows=3D26112.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D= 192
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Hash = =C2=A0(cost=3D29.67..29.67 rows=3D1667 width=3D28) (actual time=3D0.749..0.= 749 rows=3D1667.00 loops=3D3)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: t.tag_1, t.tag_2, t.entity_id, t.from_d= ay, t.to_day
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Buckets: 2048 =C2=A0Batches: 1 =C2=A0Memory Usage: 120kB
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers:= shared hit=3D39
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D0.679..0.679 rows=3D1667.00 lo= ops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 Buffers: shared hit=3D13
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual time=3D0.621.= .0.622 rows=3D1667.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D13
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0= Seq Scan on public.entity_tags t =C2=A0(cost=3D0.00..29.67 rows=3D1667 widt= h=3D28) (actual time=3D0.058..0.388 rows=3D1667.00 loops=3D3)
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 Output: t.tag_1, t.tag_2, t.entity_id, t.from_day, t.to_day
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 Buffers: shared hit=3D39
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2= =A0actual time=3D0.092..0.420 rows=3D1667.00 loops=3D1
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 Buffers: shared hit=3D13
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual= time=3D0.072..0.321 rows=3D1667.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 B= uffers: shared hit=3D13


<= div>
On PG18 pruning is also restored keeping the view but performin= g a single "group by" instead of multiple grouping sets:
select t.tag_1, sum(<= span style=3D"font-family:"JetBrains Mono",monospace;color:rgb(0,= 0,0)">m.duration) as duration, sum(m.counter) as counter, sum(m<= /span>.amount) a= s amount
from monthly_data_= view m
join entity_tags t <= /span>on m.entity_= id =3D t.entit= y_id and m.month between t.from_day and t.to_day
where m.month between '2026-02-01&= #39;::date and '= 2026-02-28'= ;::date
group by = t.tag_1;

Finalize GroupAggreg= ate =C2=A0(cost=3D81682.97..81698.65 rows=3D50 width=3D32) (actual time=3D3= 56.116..358.029 rows=3D50.00 loops=3D1)
=C2=A0 Output: t.t= ag_1, sum(monthly_data.duration), sum(monthly_data.counter), sum(monthly_da= ta.amount)
=C2=A0 Group Key: t.tag_1
=C2= =A0 Buffers: shared hit=3D22114
=C2=A0 -> =C2=A0Gather = Merge =C2=A0(cost=3D81682.97..81696.95 rows=3D120 width=3D32) (actual time= =3D356.111..358.009 rows=3D150.00 loops=3D1)
=C2=A0 =C2=A0= =C2=A0 =C2=A0 Output: t.tag_1, (PARTIAL sum(monthly_data.duration)), (PART= IAL sum(monthly_data.counter)), (PARTIAL sum(monthly_data.amount))=C2=A0 =C2=A0 =C2=A0 =C2=A0 Workers Planned: 2
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 Workers Launched: 2
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 Buffers: shared hit=3D22114
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 -> =C2=A0Sort =C2=A0(cost=3D80682.95..80683.07 rows=3D= 50 width=3D32) (actual time=3D349.568..349.570 rows=3D50.00 loops=3D3)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: t.tag= _1, (PARTIAL sum(monthly_data.duration)), (PARTIAL sum(monthly_data.counter= )), (PARTIAL sum(monthly_data.amount))
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Sort Key: t.tag_1
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Sort Method: quicksort =C2=A0Memo= ry: 27kB
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = Buffers: shared hit=3D22114
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D346.658..346.660 rows=3D= 50.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 Sort Method: quicksort =C2=A0Memory: 27kB
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit= =3D7385
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 W= orker 1: =C2=A0actual time=3D346.663..346.665 rows=3D50.00 loops=3D1=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Sort Met= hod: quicksort =C2=A0Memory: 27kB
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D7235
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Partial HashA= ggregate =C2=A0(cost=3D80681.04..80681.54 rows=3D50 width=3D32) (actual tim= e=3D349.530..349.533 rows=3D50.00 loops=3D3)
=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: t.tag_1, P= ARTIAL sum(monthly_data.duration), PARTIAL sum(monthly_data.counter), PARTI= AL sum(monthly_data.amount)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Group Key: t.tag_1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Ba= tches: 1 =C2=A0Memory Usage: 32kB

=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D22098
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Worker 0: =C2=A0actual time=3D346.608..346.611 rows=3D50.00 loop= s=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 Batches: 1 =C2=A0Memory Usage: 32kB
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 Buffers: shared hit=3D7377

=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual time= =3D346.615..346.618 rows=3D50.00 loops=3D1
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Batches: 1 = =C2=A0Memory Usage: 32kB
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D7227
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 -> =C2=A0Hash Join =C2=A0(cost=3D50.51..78365.76 rows=3D23152= 8 width=3D20) (actual time=3D0.936..260.236 rows=3D1000000.00 loops=3D3)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: t.tag_1, monthly_data.duration, mon= thly_data.counter, monthly_data.amount
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 H= ash Cond: (monthly_data.entity_id =3D t.entity_id)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Join Filter: ((monthly_data.month >=3D t.from_day) AND (month= ly_data.month <=3D t.to_day))
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Rows Rem= oved by Join Filter: 667154
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: sha= red hit=3D22098
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual tim= e=3D1.031..261.125 rows=3D1001480.00 loops=3D1
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 Buffers: shared hit=3D7377
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 W= orker 1: =C2=A0actual time=3D0.947..259.326 rows=3D981104.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D7227
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 -> =C2=A0Parallel Seq Scan on public.monthly_data_2= 02602 monthly_data =C2=A0(cost=3D0.00..40809.00 rows=3D1250000 width=3D20) = (actual time=3D0.027..79.622 rows=3D1000000.00 loops=3D3)

= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: monthly_data.duration, month= ly_data.counter, monthly_data.amount, monthly_data.entity_id, monthly_data.= month
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Filter: ((month= ly_data.month >=3D '2026-02-01'::date) AND (monthly_data.month &= lt;=3D '2026-02-28'::date))
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 Buffers: shared hit=3D22059
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D0.030..80.173 row= s=3D1001480.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 Buffers: shared hit=3D7364
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual time=3D0.031..82.531 rows=3D981= 104.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Buffers: shared hit=3D7214
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2= =A0Hash =C2=A0(cost=3D29.67..29.67 rows=3D1667 width=3D20) (actual time=3D0= .895..0.895 rows=3D1667.00 loops=3D3)
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 Output: t.tag_1, t.entity_id, t.from_day, t.to_day=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buckets: 2048 =C2=A0Batche= s: 1 =C2=A0Memory Usage: 106kB
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 Buffers: shared hit=3D39
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 Worker 0: =C2=A0actual time=3D0.983..0.983 rows=3D1667.00= loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 B= uffers: shared hit=3D13
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Worker 1: =C2=A0actual time=3D0.898..0.898 rows=3D1667.00 loops=3D1

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared= hit=3D13
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -> =C2= =A0Seq Scan on public.entity_tags t =C2=A0(cost=3D0.00..29.67 rows=3D1667 w= idth=3D20) (actual time=3D0.081..0.542 rows=3D1667.00 loops=3D3)
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output: = t.tag_1, t.entity_id, t.from_day, t.to_day
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D39
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Work= er 0: =C2=A0actual time=3D0.118..0.540 rows=3D1667.00 loops=3D1
<= span style=3D"font-family:"JetBrains Mono",monospace;color:rgb(8,= 8,8)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buff= ers: shared hit=3D13

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 Worker 1: =C2=A0actual time=3D0.117..0.483 rows=3D= 1667.00 loops=3D1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 Buffers: shared hit=3D13
--00000000000053aab3064e64c8ed--