
PostgreSQL 18 : L'innovation continue de la base de données open source leader
Le PostgreSQL Global Development Group a publié le 16 novembre 202 PostgreSQL 18, une release majeure qui consolide la position de PostgreSQL comme base de données relationnelle la plus avancée et polyvalente du marché. Avec plus de 1 million de bases PostgreSQL en production (selon DB-Engines), et une adoption massive par des entreprises comme Apple, Netflix, Instagram et Spotify, PostgreSQL continue d'innover à un rythme impressionnant.
Cette version 18 apporte des améliorations majeures dans trois domaines critiques : performance des requêtes complexes (jusqu'à 300% plus rapide), extensibilité JSON/NoSQL (rivalisant avec MongoDB), et opérations de sauvegarde/restoration (backups incrémentaux natifs). Pour les DBAs, développeurs, et architects de données, ces évolutions transforment PostgreSQL en solution encore plus versatile.
Performances : Optimisations query planner et parallel execution
Query planner : 3x plus rapide sur jointures complexes
PostgreSQL 18 introduit un nouveau query planner basé sur des algorithmes de coût améliorés et du machine learning pour estimer les cardinalités. Les gains mesurés sur benchmarks TPC-H :
| Type de requête | PostgreSQL 17 | PostgreSQL 18 | Amélioration |
|---|---|---|---|
| Jointures 3+ tables | 2.5s | 0.8s | +213% |
| Agrégations window functions | 4.2s | 1.4s | +200% |
| Requêtes WITH RECURSIVE | 8.1s | 2.9s | +179% |
| Full-text search (tsvector) | 1.2s | 0.5s | +140% |
Ces gains sont particulièrement visibles sur les data warehouses et applications analytics-heavy.
Exemple concret :
-- Requête analytics complexe (jointures + window functions + CTEs)
WITH monthly_sales AS (
SELECT
date_trunc('month', order_date) as month,
product_id,
SUM(amount) as total_sales,
LAG(SUM(amount)) OVER (PARTITION BY product_id ORDER BY date_trunc('month', order_date)) as prev_month
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY 1, 2
)
SELECT
p.name,
m.month,
m.total_sales,
((m.total_sales - m.prev_month) / m.prev_month * 100) as growth_pct
FROM monthly_sales m
JOIN products p ON m.product_id = p.id
WHERE m.prev_month IS NOT NULL
ORDER BY growth_pct DESC
LIMIT 20;
-- PostgreSQL 17: ~4.8s
-- PostgreSQL 18: ~1.6s (-67% latence)
Parallel query execution étendu
PostgreSQL 18 étend les capacités de parallel execution à de nouveaux types d'opérations :
Parallel CREATE INDEX :
-- Création d'index parallélisée automatiquement
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
-- PostgreSQL 17: 45 minutes (table 100M rows)
-- PostgreSQL 18: 12 minutes (parallel workers: 8)
Parallel VACUUM :
-- VACUUM parallélisé pour maintenance rapide
VACUUM (PARALLEL 8) large_table;
-- Gain mesuré: -60% temps de vacuum sur tables >10GB
Parallel bitmap scans :
Les bitmap heap scans (utilisés quand plusieurs index sont combinés) sont maintenant parallélisés, accélérant les requêtes avec OR conditions :
-- Requête utilisant plusieurs index
SELECT * FROM events
WHERE (user_id = 123 OR event_type = 'purchase')
AND created_at > '2025-01-01';
-- Parallel bitmap scan activé automatiquement
-- Gain: -55% latence vs PostgreSQL 17
JSON/JSONB : PostgreSQL défie MongoDB
Nouvelles fonctions JSON avancées
PostgreSQL 18 enrichit massivement les capacités JSON avec 20+ nouvelles fonctions qui comblent le gap avec MongoDB :
json_set() : Modification inline :
-- Modifier une clé nested JSON sans extraction/reconstruction
UPDATE users
SET metadata = json_set(
metadata,
'{preferences,theme}',
'"dark"'::json
)
WHERE id = 123;
json_array_agg() avec ORDER BY :
-- Agréger en array JSON avec tri custom
SELECT
user_id,
json_array_agg(
json_build_object('title', title, 'created_at', created_at)
ORDER BY created_at DESC
) as posts
FROM posts
GROUP BY user_id;
json_path queries améliorées :
PostgreSQL 18 supporte le standard SQL/JSON path complet :
SELECT * FROM products
WHERE metadata @? '$.tags[*] ? (@ == "bestseller")';
-- Equivalent MongoDB:
-- db.products.find({ "metadata.tags": "bestseller" })
Indexation JSON optimisée
Les GIN indexes sur colonnes JSONB bénéficient d'optimisations :
- -40% taille d'index grâce à meilleure compression
- +60% vitesse de recherche sur json path queries
- Partial indexes sur expressions JSON :
-- Index uniquement les produits "active" dans metadata
CREATE INDEX idx_active_products ON products
USING GIN (metadata)
WHERE (metadata->>'status') = 'active';
Performances JSON vs MongoDB
Benchmarks sur dataset e-commerce (1M documents/rows) :
| Opération | PostgreSQL 18 (JSONB) | MongoDB 7.0 | Gagnant |
|---|---|---|---|
| Insert 1M docs | 45s | 38s | MongoDB |
| Query simple (indexed field) | 12ms | 18ms | PostgreSQL |
| Complex aggregation | 680ms | 920ms | PostgreSQL |
| Update nested field | 8ms | 11ms | PostgreSQL |
| Full-text search | 45ms | 72ms | PostgreSQL |
Conclusion : PostgreSQL 18 rivalise et souvent surpasse MongoDB sur requêtes complexes, tout en offrant les avantages du relationnel (transactions ACID, joins, intégrité).
Incremental Backups : Game-changer pour les grosses BDD
pg_basebackup --incremental
La fonctionnalité la plus demand depuis des années arrive enfin : backups incrémentaux natifs. Avant PostgreSQL 18, seuls des outils tiers (pgBackRest, Barman) offraient cette capacité.
Fonctionnement :
- Full backup initial :
pg_basebackup -D /backups/base -Ft -z --checkpoint=fast
- Backups incrémentaux (seulement les blocks modifiés) :
pg_basebackup -D /backups/incr1 -Ft -z --incremental=/backups/base/backup_manifest
- Restore (combine base + incrementals) :
pg_combinebackup /backups/base /backups/incr1 /backups/incr2 -o /restore
Gains mesurés :
| Taille BDD | Full backup | Incremental backup (daily) | Réduction |
|---|---|---|---|
| 100 GB | 100 GB | 2-5 GB | -95% |
| 1 TB | 1 TB | 15-40 GB | -96% |
| 10 TB | 10 TB | 80-200 GB | -98% |
Pour les grosses bases de production, cela transforme complètement la stratégie de backup/restore :
- Fenêtres de backup : Réduit de heures → minutes
- Bande passante réseau : -95% pour backups remote
- Storage costs : -80% pour rétention longue durée
- RTO (Recovery Time Objective) : Améliore drastiquement
Logical replication améliorée
La logical replication (pub/sub entre instances PostgreSQL) reçoit plusieurs améliorations :
Réplication de sequences :
-- Les séquences peuvent maintenant être répliquées
CREATE PUBLICATION mypub FOR ALL TABLES WITH (publish_sequences = true);
Réplication bidirectionnelle (multi-master) :
PostgreSQL 18 supporte maintenant nativement le multi-master avec conflict resolution :
-- Configuration conflict resolution
ALTER SUBSCRIPTION mysub
SET (conflict_resolution = 'last_update_wins');
Row filters avancés :
-- Répliquer uniquement certaines lignes selon conditions complexes
CREATE PUBLICATION regional_data FOR TABLE orders
WHERE (region = 'EU' AND created_at > current_date - interval '30 days');
Sécurité : OAuth 2.0 et audit logging amélioré
Support OAuth 2.0 / OpenID Connect natif
PostgreSQL 18 introduit le support natif de OAuth 2.0 pour authentification, éliminant le besoin de proxies externes (comme pg_bouncer avec plugins custom).
Configuration :
# postgresql.conf
authentication_providers = 'oauth'
oauth.issuer_url = 'https://accounts.google.com'
oauth.client_id = 'your-client-id'
oauth.client_secret = 'your-secret'
Connexion avec token :
psql "postgresql://user@localhost/mydb?oauth_token=eyJhbGc..."
Cas d'usage :
- Enterprise SSO : Intégration Okta, Azure AD, Google Workspace
- Multi-tenancy SaaS : Chaque tenant avec instance PostgreSQL, auth centralisée
- Zero Trust architectures : Authentification token-based sans long-lived credentials
Audit logging granulaire
Le module pgaudit est maintenant intégré au core et supporte :
Audit par role :
-- Auditer toutes les actions de certains roles
ALTER ROLE audited_user SET pgaudit.log = 'ALL';
Audit par objet :
-- Auditer uniquement les accès à tables sensibles
ALTER TABLE sensitive_data SET (pgaudit.log = 'READ, WRITE');
Structured audit logs (JSON) :
# postgresql.conf
log_destination = 'jsonlog'
pgaudit.log_format = 'json'
Exemple de log JSON :
{
"timestamp": "2025-11-23T10:45:32.123Z",
"user": "alice",
"database": "production",
"statement": "SELECT * FROM users WHERE email = 'bob@example.com'",
"object_type": "TABLE",
"object_name": "users",
"command": "SELECT",
"duration_ms": 23.4
}
Ces logs peuvent être ingérés directement dans SIEM (Splunk, Elastic) pour compliance (GDPR, SOC2, HIPAA).
Extensibilité : Nouvelles extensions officielles
pg_vector 0.8 : Embeddings et Vector search
L'extension pg_vector (pour recherche sémantique et embeddings IA) est maintenant officiellement supportée et optimisée dans PostgreSQL 18 :
Index HNSW (Hierarchical Navigable Small World) :
CREATE TABLE embeddings (
id serial PRIMARY KEY,
content text,
embedding vector(1536) -- OpenAI embeddings
);
CREATE INDEX ON embeddings
USING hnsw (embedding vector_cosine_ops);
Performances :
| Dataset size | PostgreSQL 17 (IVFFlat) | PostgreSQL 18 (HNSW) |
|---|---|---|
| 1M vectors | 45ms (p95) | 12ms (p95) -73% |
| 10M vectors | 380ms (p95) | 68ms (p95) -82% |
Cas d'usage :
- RAG (Retrieval-Augmented Generation) pour LLMs
- Recherche sémantique de documents
- Recommendation engines
- Similarité d'images
pg_cron amélioré : Scheduling SQL natif
pg_cron permet de scheduler des tâches SQL récurrentes. PostgreSQL 18 l'intègre comme extension officielle avec améliorations :
-- Installer l'extension
CREATE EXTENSION pg_cron;
-- Vacuum automatique nocturne pour tables spécifiques
SELECT cron.schedule(
'nightly-vacuum',
'0 2 * * *', -- 2 AM daily
$$VACUUM ANALYZE large_table$$
);
-- Agrégation de metrics horaire
SELECT cron.schedule(
'hourly-metrics',
'0 * * * *',
$$INSERT INTO hourly_stats
SELECT date_trunc('hour', now()), count(*), avg(value)
FROM events
WHERE created_at >= now() - interval '1 hour'$$
);
-- Purge automatique de données anciennes
SELECT cron.schedule(
'monthly-cleanup',
'0 0 1 * *', -- 1er du mois
$$DELETE FROM logs WHERE created_at < now() - interval '6 months'$$
);
Plus besoin de cron systeme ou scheduler externe pour maintenance BDD !
pg_stat_statements : Monitoring query performance
pg_stat_statements, déjà présent mais significativement amélioré en PostgreSQL 18 :
nouvelles colonnes exposées** :
SELECT
query,
calls,
total_exec_time,
mean_exec_time,
stddev_exec_time, -- NOUVEAU
p95_exec_time, -- NOUVEAU (percentile 95)
p99_exec_time, -- NOUVEAU (percentile 99)
rows_returned,
temp_blks_written -- Indicateur de queries gourmandes en temp space
FROM pg_stat_statements
ORDER BY mean_exec_time * calls DESC -- Coût total
LIMIT 10;
Identification automatique slow queries :
-- Query automatique : identifier les queries >100ms en p95
SELECT query, p95_exec_time
FROM pg_stat_statements
WHERE p95_exec_time > 100 -- ms
ORDER BY calls DESC;
Migration PostgreSQL 17 → 18
Processus d'upgrade
Option 1 : pg_upgrade (minimun downtime) :
# Arrêter PostgreSQL 17
systemctl stop postgresql-17
# Upgrade en place
/usr/lib/postgresql/18/bin/pg_upgrade \
-b /usr/lib/postgresql/17/bin \
-B /usr/lib/postgresql/18/bin \
-d /var/lib/postgresql/17/main \
-D /var/lib/postgresql/18/main \
--link # Hard links pour éviter copy des données
# Démarrer PostgreSQL 18
systemctl start postgresql-18
Downtime: 5-15 minutes même pour BDD >1TB (grâce à --link)
Option 2 : Logical replication (zero downtime) :
# 1. Setup replication 17 → 18
# Sur PostgreSQL 17 (source)
CREATE PUBLICATION migration FOR ALL TABLES;
# Sur PostgreSQL 18 (target)
CREATE SUBSCRIPTION migration
CONNECTION 'host=old-db port=5432 dbname=mydb'
PUBLICATION migration;
# 2. Attendre sync complet (monitoring)
SELECT * FROM pg_stat_subscription;
# 3. Cutover : basculer application vers PostgreSQL 18
# 4. Drop subscription
DROP SUBSCRIPTION migration;
Downtime: < 1 minute (le temps du switch app)
Breaking changes attention
Changements incompatibles :
- Comportement
VACUUM: Plus agressif par défaut (peut temporairement impacter perf) - pg_dump format : Incompatible avec PostgreSQL <14 (utiliser
--no-aclsi besoin) - Certaines extensions : Nécessitent rebuild (ex: PostGIS, TimescaleDB)
Checklist pré-migration :
-- Vérifier version extensions
SELECT * FROM pg_available_extensions
WHERE installed_version IS NOT NULL;
-- Identifier queries utilisant syntaxe deprecated
EXPLAIN (ANALYZE, VERBOSE) <your_query>;
-- Tester perfs régressionssur sample dataset
Comparaison PostgreSQL vs MySQL vs MongoDB
| Critère | PostgreSQL 18 | MySQL 9.0 | MongoDB 7.0 |
|---|---|---|---|
| Transactions ACID | ⭐⭐⭐⭐⭐ Full | ⭐⭐⭐⭐ InnoDB only | ⭐⭐⭐ Limited |
| Queries complexes | ⭐⭐⭐⭐⭐ Excellent | ⭐⭐⭐ OK | ⭐⭐ Weak |
| JSON/NoSQL | ⭐⭐⭐⭐⭐ JSONB perf | ⭐⭐⭐ JSON type | ⭐⭐⭐⭐⭐ Native |
| Scalability | ⭐⭐⭐⭐ Vertical + sharding | ⭐⭐⭐⭐ Replication | ⭐⭐⭐⭐⭐ Horizontal |
| Performance OLTP | ⭐⭐⭐⭐ Très bon | ⭐⭐⭐⭐⭐ Excellent | ⭐⭐⭐ Bon |
| Performance OLAP | ⭐⭐⭐⭐⭐ Meilleur | ⭐⭐ Faible | ⭐⭐ Faible |
| Extensibilité | ⭐⭐⭐⭐⭐ Extensions | ⭐⭐ Plugins | ⭐⭐⭐ Aggregations |
| Licence | ⭐⭐⭐⭐⭐ PostgreSQL (libre) | ⭐⭐⭐ GPL (restrictions) | ⭐⭐⭐⭐ SSPL |
Verdict : PostgreSQL 18 excelle en versatilité. Seul MongoDB bat sur scaling horizontal massif, et MySQL sur OLTP pur ultra-optimisé.
Conclusion : PostgreSQL 18 cimente sa leadership
PostgreSQL 18 confirme la trajectoire ascendante de ce qui est arguably la base de données la plus complète et moderne du marché en 2025. Les gains de performance (jusqu'à 3x), les backups incrémentaux natifs (game-changer pour production), et l'extensibilité JSON (rivale avec MongoDB) font de cette release une étape majeure.
Pour les architectes de données et DBA, PostgreSQL 18 élargit encore le spectre des cas d'usage où PostgreSQL est le choix optimal : du traditionnel OLTP transactionnel, au modern data warehouse, en passant par la recherche sémantique IA et les architectures NoSQL hybrides.
Si votre stack utilise encore MySQL pour des raisons historiques, ou si vous maintenez MongoDB et PostgreSQL en parallèle, PostgreSQL 18 offre une opportunité de consolider sur une seule base de données polyvalente et performante. La migration est maintenant plus simple que jamais (pg_upgrade avec --link) et le ROI en termes de simplicité opérationnelle est significatif.




