novinka v pg 19 - eager agregace

15 views
Skip to first unread message

Pavel Stehule

unread,
Oct 9, 2025, 2:28:05 PM (5 days ago) Oct 9
to PostgreSQL-cz
Ahoj

jestli nedojde k nejakym problemum, tak urcite dost zajimavou ficurou v pg19 bude eager agregace (jak byste to prelozili do cestiny?). V podstate jde o to, ze to umi automaticky predradit agregace pred joiny. Pokud si vzpominam, tahle schopnost se povazovala za zasadni ficuru ve starych microsoftich SQL serverech. V postgresu to slo taky - rucne.

(2025-10-09 20:14:36) postgres=# explain analyze select sum, nazev from (select sum(pocet_muzu+pocet_zen), okres_id from obce group by okres_id) s join okresy on okresy.id = s.okres_id;
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                         QUERY PLAN                                                         │
╞════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ Hash Join  (cost=170.11..172.09 rows=77 width=18) (actual time=14.611..14.757 rows=77.00 loops=1)                          │
│   Hash Cond: (okresy.id = (obce.okres_id)::text)                                                                           │
│   Buffers: shared hit=60                                                                                                   │
│   ->  Seq Scan on okresy  (cost=0.00..1.77 rows=77 width=17) (actual time=0.037..0.059 rows=77.00 loops=1)                 │
│         Buffers: shared hit=1                                                                                              │
│   ->  Hash  (cost=169.15..169.15 rows=77 width=15) (actual time=14.561..14.562 rows=77.00 loops=1)                         │
│         Buckets: 1024  Batches: 1  Memory Usage: 12kB                                                                      │
│         Buffers: shared hit=59                                                                                             │
│         ->  HashAggregate  (cost=168.38..169.15 rows=77 width=15) (actual time=14.415..14.476 rows=77.00 loops=1)          │
│               Group Key: obce.okres_id                                                                                     │
│               Batches: 1  Memory Usage: 32kB                                                                               │
│               Buffers: shared hit=59                                                                                       │
│               ->  Seq Scan on obce  (cost=0.00..121.50 rows=6250 width=15) (actual time=0.015..2.076 rows=6250.00 loops=1) │
│                     Buffers: shared hit=59                                                                                 │
│ Planning Time: 0.577 ms                                                                                                    │
│ Execution Time: 14.920 ms                                                                                                  │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
(16 rows)

-- set enable_eager_aggregate to off;
Time: 16,905 ms
(2025-10-09 20:14:40) postgres=# explain analyze select sum(pocet_muzu + pocet_zen), okresy.nazev from obce join okresy on obce.okres_id = okresy.id group by okresy.nazev;
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                       QUERY PLAN                                                       │
╞════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ HashAggregate  (cost=188.41..189.18 rows=77 width=18) (actual time=25.463..25.522 rows=77.00 loops=1)                  │
│   Group Key: okresy.nazev                                                                                              │
│   Batches: 1  Memory Usage: 32kB                                                                                       │
│   Buffers: shared hit=60                                                                                               │
│   ->  Hash Join  (cost=2.73..141.54 rows=6250 width=18) (actual time=0.237..15.852 rows=6250.00 loops=1)               │
│         Hash Cond: ((obce.okres_id)::text = okresy.id)                                                                 │
│         Buffers: shared hit=60                                                                                         │
│         ->  Seq Scan on obce  (cost=0.00..121.50 rows=6250 width=15) (actual time=0.023..2.574 rows=6250.00 loops=1)   │
│               Buffers: shared hit=59                                                                                   │
│         ->  Hash  (cost=1.77..1.77 rows=77 width=17) (actual time=0.200..0.202 rows=77.00 loops=1)                     │
│               Buckets: 1024  Batches: 1  Memory Usage: 12kB                                                            │
│               Buffers: shared hit=1                                                                                    │
│               ->  Seq Scan on okresy  (cost=0.00..1.77 rows=77 width=17) (actual time=0.019..0.086 rows=77.00 loops=1) │
│                     Buffers: shared hit=1                                                                              │
│ Planning:                                                                                                              │
│   Buffers: shared hit=16                                                                                               │
│ Planning Time: 1.124 ms                                                                                                │
│ Execution Time: 25.691 ms                                                                                              │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
(18 rows)

Time: 28,566 ms
(2025-10-09 20:14:53) postgres=# set enable_eager_aggregate to on;
SET
Time: 0,832 ms
(2025-10-09 20:15:07) postgres=# explain analyze select sum(pocet_muzu + pocet_zen), okresy.nazev from obce join okresy on obce.okres_id = okresy.id group by okresy.nazev;
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                         QUERY PLAN                                                         │
╞════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ Finalize HashAggregate  (cost=172.48..173.25 rows=77 width=18) (actual time=15.077..15.132 rows=77.00 loops=1)             │
│   Group Key: okresy.nazev                                                                                                  │
│   Batches: 1  Memory Usage: 32kB                                                                                           │
│   Buffers: shared hit=60                                                                                                   │
│   ->  Hash Join  (cost=171.11..172.09 rows=77 width=18) (actual time=14.725..14.928 rows=77.00 loops=1)                    │
│         Hash Cond: ((obce.okres_id)::text = okresy.id)                                                                     │
│         Buffers: shared hit=60                                                                                             │
│         ->  Partial HashAggregate  (cost=168.38..169.15 rows=77 width=15) (actual time=14.535..14.613 rows=77.00 loops=1)  │
│               Group Key: obce.okres_id                                                                                     │
│               Batches: 1  Memory Usage: 32kB                                                                               │
│               Buffers: shared hit=59                                                                                       │
│               ->  Seq Scan on obce  (cost=0.00..121.50 rows=6250 width=15) (actual time=0.013..2.079 rows=6250.00 loops=1) │
│                     Buffers: shared hit=59                                                                                 │
│         ->  Hash  (cost=1.77..1.77 rows=77 width=17) (actual time=0.175..0.177 rows=77.00 loops=1)                         │
│               Buckets: 1024  Batches: 1  Memory Usage: 12kB                                                                │
│               Buffers: shared hit=1                                                                                        │
│               ->  Seq Scan on okresy  (cost=0.00..1.77 rows=77 width=17) (actual time=0.030..0.086 rows=77.00 loops=1)     │
│                     Buffers: shared hit=1                                                                                  │
│ Planning:                                                                                                                  │
│   Buffers: shared hit=16                                                                                                   │
│ Planning Time: 1.254 ms                                                                                                    │
│ Execution Time: 15.324 ms                                                                                                  │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
(22 rows)


Na malem testu to funguje hezky - jen ty provadeci plany budou zase o neco slozitejsi.

Poradny kus prace na tehle ficure udelal Tonda.

Pavel


Antonin Houska

unread,
Oct 10, 2025, 8:03:02 AM (4 days ago) Oct 10
to postgr...@googlegroups.com
Pavel Stehule <pavel....@gmail.com> wrote:

> Ahoj
>
> jestli nedojde k nejakym problemum, tak urcite dost zajimavou ficurou v pg19 bude eager agregace (jak byste to prelozili do cestiny?). V
> podstate jde o to, ze to umi automaticky predradit agregace pred joiny. Pokud si vzpominam, tahle schopnost se povazovala za zasadni ficuru
> ve starych microsoftich SQL serverech. V postgresu to slo taky - rucne.
> ...
> Poradny kus prace na tehle ficure udelal Tonda.

Ani mi o tom nemluv :-) Do konference pgsql-hackers jsem to poslal před více
než 8 lety. Po nějaké době mi ale došlo, že Tom Lane (tzn. tehdy asi jedinný
committer, který této části optimizeru rozumí dostatečně na to, aby to mohl do
PG přidat), se k tomu moc nemá, tak jsem to vzdal. Nechtělo se mi riskovat, že
na tom promarním ještě víc času. Před pár lety se ale objevil nový committer,
který se taky specializuje na optimizer, a ten to před pár dny dokončil. Tak
aspoň že ta práce nepřišla vniveč. Napříště se ale už do takto rozsáhlých
projektů pouštět nebudu.

Tonda H.

Pavel Stehule

unread,
Oct 10, 2025, 9:57:47 AM (4 days ago) Oct 10
to postgr...@googlegroups.com
Ahoj

pá 10. 10. 2025 v 14:03 odesílatel 'Antonin Houska' via PostgreSQL-cz <postgr...@googlegroups.com> napsal:
Vim o cem mluvis. Skoro cokoliv je dneska v Postgresu komplikace - jednak je to v podstate 40 let stary soft, druhak to pouzivaji miliony lidi na planete, a nikdo nechce udelat nejaky pruser.
Ale porad tam ten vyvoj je - i kdyz nektery veci trvaji brutalne dlouho - treba json_table je relativne izolovana ficura, a jeste neni kompletni a od prototypu je to 5 let. Redukce zbytecnych joinu, nebo index skip scan. Asi se Postgres dostava do stavu, kdy jednu ficuru nemuze dat jeden clovek - jeden to vykopne, prorazi - a druhy to docisti a dotahne - oboji je prace na nekolik let, a oboji je stejne dulezite - jedno by nebylo bez druheho. 


Tonda H.

--
Tuto zprávu jste obdrželi, protože jste přihlášeni k odběru skupiny PostgreSQL-cz ve Skupinách Google.
Chcete-li zrušit odběr skupiny a přestat dostávat e‑maily ze skupiny, zašlete e-mail na adresu postgresql-c...@googlegroups.com.
Tuto diskuzi najdete na adrese https://groups.google.com/d/msgid/postgresql-cz/17573.1760097749%40localhost.
Reply all
Reply to author
Forward
0 new messages