La versione PostgreSQL 19 introduce nuove funzionalita' all'RDBMS Open Source piu' avanzato ed oggi [NdA 2026-04-01] e' il giorno giusto per parlarne: ecco quindi pubblicato questo documento!
In generale la versione 19 e' un'evoluzione della versione precedente con nuove funzionalita' ma anche con migliori prestazioni ed un costante miglioramento degli aspetti di gestione delle basi dati.
In questo documento sono riportati in dettaglio alcuni nuovi elementi introdotti nella versione 19, riportando esempi pratici di utilizzo:
Ma le novita' non sono solo queste... continuate a leggere!
L'esempio dovrebbe essere chiaro: possiamo usare gli HINT con PostgreSQL!
Non si tratta propriamente di HINT ma di suggerimenti passati all'ottimizzatore,
il funzionamento tuttavia e' analogo.
Il plan advice opera
in modo integrato e consistente con l'EXPLAIN che puo' indicare
se e quanto un advice e' stato applicato.
Oltre a pg_plan_advice e' disponibile anche pg_stash_advice
[NdA la cui configurazione
e' banale (simile a quella dell'auto_explain),
poi e' sufficiente lo statement CREATE EXTENSION pg_stash_advice per poterla utilizzare]
che consente di legare un advice_string ad uno specifico query_id.
Si tratta solo di una estensione come contrib module
ma e', a mio avviso, un importante cambio di approccio nella gestione dei piani d'esecuzione.
La posizione ufficiale
(eg. Optimizer and Query Hints Discussion)
era infatti che se l'ottimizzatore sbagliava nella scelta del piano
il problema era altrove ed era necessario correggerlo alla fonte
(disegno logico/fisico errato, ANALYZE non aggiornate, query da riscrivere)
e non indicando un piano alternativo.
E' vero ma nella pratica, solo in casi particolari e con la dovuta cautela,
fornire un suggerimento o un HINT Advice al planner consente di aggirare velocemente
un problema per poi risolverne la causa con il tempo necessario.
Lo sanno bene sia la community che ha sviluppato l'ottima estensione
pg_hint_plan
[NdA non e' l'unica estensione arrivata dal sol di levante]
che chi ha sviluppato fork di PostgreSQL con soluzioni alternative
(eg. Aurora PostgreSQL
EDB PostgreSQL Advanced Server).
Ma pg_hint_plan, sebbene disponibile sulla maggioranza dei servizi di PostgreSQL in Cloud,
non fa parte delle core extensions e quindi richiede un configurazione specifica;
mentre pg_plan_advice ha una configurazione standard
ed e' integrato con l'EXPLAIN PLAN.
Come sempre la documentazione ufficiale riporta tutti i dettagli ma una descrizione piu' sintetica si trova in questa paginetta.
Un esempio spesso e' piu' utile di una precisa ma noiosa descrizione!
PG19 introduce la possibilita' di rappresentare le strutture a grafo in modo nativo nel modello relazionale indicando come i nodi (vertex) si relazionano (edge) tra loro, come definito nello standard SQL/PGQ (ISO/IEC 9075-16:2023). Nel catalogo sono state aggiunte 5 nuove viste: pg_propgraph_element, pg_propgraph_label, pg_propgraph_property, pg_propgraph_element_label, e pg_propgraph_label_property che descrivono ogni proprieta' dei grafi.
Una volta definito il grafo possiamo interrogarlo con una clausola SQL:
Un elemento di internal: PostgreSQL utilizza i metadati con la definizione del grafo per convertire le richieste delle query grafiche in un normale statement SQL che viene eseguito poi normalmente dal Planner:
QUERY PLAN
----------------------------------------------------------------------------------
Nested Loop (cost=28.23..65.77 rows=10 width=32)
-> Hash Join (cost=28.07..63.85 rows=10 width=4)
Hash Cond: (knows.dst_id = person_1.id)
-> Seq Scan on knows (cost=0.00..30.40 rows=2040 width=8)
-> Hash (cost=28.00..28.00 rows=6 width=4)
-> Seq Scan on person person_1 (cost=0.00..28.00 rows=6 width=4)
Filter: ((age >= 30) AND (age <= 40))
-> Index Scan using person_pkey on person (cost=0.15..0.19 rows=1 width=36)
Index Cond: (id = knows.src_id)
Generated Plan Advice:
JOIN_ORDER(knows person#2 person)
NESTED_LOOP_PLAIN(person)
HASH_JOIN(person#2)
SEQ_SCAN(knows person#2)
INDEX_SCAN(person public.person_pkey)
NO_GATHER(person knows person#2)
Come sempre la documentazione ufficiale riporta tutti i dettagli ma una descrizione piu' sintetica si trova in questa paginetta.
Si tratta di un comando molto semplice, con funzionalita' analoghe ai comandi VACUUM e CLUSTER ma con un'importante novita': con REPACK (CONCURRENTLY) table_name; viene ricostruita fisicamente la tabella come con un VACUUM FULL ma con un lock analogo ad un normale VACUUM.
Come e' noto un VACUUM FULL utilizza il pesante
ACCESS EXCLUSIVE per tutto il tempo dell'operazione
mentre il nuovo comando REPACK con l'opzione CONCURRENTLY utilizza il lock
ACCESS EXCLUSIVE solo all'inizio ed alla fine dell'attivita'
per l'inizializzazione ed il cambio del relfilenode,
ed un meno pesante SHARE UPDATE EXCLUSIVE per effettuare
la lunga e pesante ricostruzione fisica dell'oggetto:
La richiesta dei due ACCESS EXCLUSIVE, seppur di brevissima durata, e' comunque un'importante differenza rispetto a quanto richiesto da un normale VACUUM perche' l'avvio di un REPACK (CONCURRENTLY) puo' essere bloccato da una semplice SELECT. Il REPACK e' una funzionalita' molto importante ed attesa da tempo.
Una funzionalita' spesso richiesta nelle applicazioni e' quella di ricercare un record e, se non lo si trova, inserirlo. L'operazione richiesta e' una Get-or-create. Dalla versione 19 PostgreSQL riesce a fornire questa funzionalita' con un solo efficiente statement SQL:
Per ottenere lo stesso risultato in precedenza era possibile utilizzare il seguente statement:
Questo statement pero' ha un importante effetto collaterale: genera un'update ad ogni conflitto
e questo con PostgreSQL vuol dire che viene creata una nuova tupla, che la tupla
precedente diverra' una dead tuple che dovra' essere ripulita dal vacuum e che,
se non e' possibile eseguire un hot update debbono essere aggiornati anche tutti gli indici.
Dal punto di vista prestazionale c'e' molta differenza!
La funzionalita' di UPSERT e' disponibile in PostgreSQL dalla 9.5,
con la nuova clausola e' possibile ottenere in modo efficiente
i seguenti diversi comportamenti da uno statement di INSERT:
| Action | Note |
| Error on duplicates. Standard SQL INSERT behaviour. | |
| DO NOTHING | Fire-and-forget. Ignores duplicates. |
| DO UPDATE | UPSERT. Always use newest values. |
| DO SELECT | Get-or-create. Idempotent operations. |
Sono frequenti query complesse che effettuano molti join e operazioni di aggregazione. Il planner di PostgreSQL ha sembre trattato questi statement eseguendo in modo ordinato prima tutti i join ed aggregando al termine. Vediamo un semplice esempio:
Con la versione 19 PostgreSQL il planner puo' utilizzare in alternativa la tecnica di aggregare i dati prima e solo al termine effettuare il lookup:
|
|
Nel caso visualizzato come esempio e' stato disabilitato il parallelismo (per rendere piu' facile il confronto) e sono state utilizzate due tabelle con 50 categorie, 5.000 dimensioni, e 2.000.000 fatti. Con la eager aggreate della versione 19 i tempi si sono ridotti del 50%. I vantaggi sono ancora maggiori quando vi sono piu' lookup o il raggruppamento ha una cardinalita' inferiore.
Certo con le precedenti versioni era possibile riscrivere la query utilizzando CTE o query annidate ottenendo tempi analoghi:
Ma su query complesse e' molto meglio che sia il Planner a determinare l'execution path migliore.
La funzionalita' e' attiva per default, si puo' disabilitare con set enable_eager_aggregate=off;
ma nella maggior parte dei casi porta a vantaggi significativi.
Quelle riportate fino ad ora non sono le uniche variazioni importanti della versione 19 di PostgreSQL. Altre novita' interessanti sono:
Avro' dimenticato qualcosa? Certamente si!
Ecco il contenuto completo della matrice delle nuove funzionalita' di PostgreSQL 19: April the 1st is too early!
Il riferimento finale e' la
documentazione ufficiale
[NdE per quando ci sara'... al momento
documentazione e' in sviluppo]
e l'ottimo prospetto riassuntivo di
pgPedia
[NdA per i piu' audaci ci sono i Commitfest
da seguire ed analizzare le feature committed].
A volte succede che qualche' funzionalita' prevista per una versione venga spostata piu' avanti nel tempo...
l'obiettivo della comunita' e' quello di mantenere stabile e ben documentato PostgreSQL.
Quindi saremo certi dell'elenco completo solo al rilascio ma alcuni commit sono gia' stati spostati al successivo CF, sigh!
PostgreSQL e' in costante evoluzione!
Per il passato:
le novita' della versione 18,
le novita' della versione 17,
le novita' della versione 16,
le novita' della versione 15,
le novita' della versione 14,
evoluzione di PostgreSQL,
...
Il tuo server puzza
e' il famigerato ma utile documento con la storia delle versioni di tutti i software che ritengo
piu' significativi, ed ovviamente anche di PostgreSQL.
Per il futuro... in realta' il futuro di PostgreSQL e' gia' adesso perche' gli sviluppi per la versione 19 sono gia' iniziati [NdA 2025-07] ed ad aprile 2026 si arrivera' al feature freeze in cui vengono fissate le nuove funzionalita' che verranno aggiunte nella versione. Arriveranno quindi le prime Beta e quindi una o piu' RC (Release Candidate) a seconda delle necessita'. Indicativamente a settembre 2026 la nuova versione PG19 sara' disponibile come produzione.
Titolo: PostgreSQL 19 - Nuove funzionalita'
Livello: Avanzato
Data: 1 Aprile 2026 🐟
Versione: 1.0.3 -
1 Maggio 2026
Autore:
mail [AT] meo.bogliolo.name