Table des matières :
- PostgreSQL vs MySQL en 2026 : différences structurelles qui comptent en production
- Performances : planificateur, indexation, JSON et partitionnement (ce qui se mesure réellement)
- Concurrence et transactions : MVCC, verrous, deadlocks et gestion de stock
- Sécurité : modèle de privilèges, chiffrement, audit et surface d’attaque
- Exploitation : sauvegardes, réplication, HA, observabilité et coûts opérationnels
- Cas d’usage e-commerce et PrestaShop : quand rester sur MySQL, quand ajouter PostgreSQL
PostgreSQL vs MySQL en 2026 : différences structurelles qui comptent en production
En 2026, comparer PostgreSQL et MySQL (ou MariaDB, souvent substitué à MySQL dans l’hébergement web) n’a plus grand-chose à voir avec une guerre de « vitesse brute ». Les deux moteurs savent tenir des charges OLTP sérieuses, mais ils divergent sur des points qui finissent par coûter cher : modèle de concurrence, richesse du SQL, extensibilité, et ergonomie d’exploitation. Dans un contexte e-commerce (PrestaShop, APIs, backoffice, imports), ces différences se traduisent en latence p95/p99, en taux de deadlocks, en temps de reprise après incident et en complexité de maintenance.
Une bonne façon d’éviter le débat « religion » est de raisonner en coûts de production :
- Coût de requêtage (est-ce que le moteur vous aide à écrire/optimiser des requêtes complexes sans hacks ?)
- Coût de concurrence (comment se comportent verrous et transactions sous pics ?)
- Coût d’exploitation (backup/PITR, réplication, maintenance, monitoring, outillage)
- Coût de changement (compatibilité applicative et écosystème — critique pour PrestaShop)
PostgreSQL (versions typiques en prod aujourd’hui : 16/17/18) a un cœur « monolithique » : un seul moteur de stockage, MVCC natif, une extensibilité massive via extensions (PostGIS, pgtrgm, pgstat_statements, etc.). MySQL (8.0+) reste architecturé autour d’InnoDB comme moteur standard : c’est stable, très éprouvé, mais certaines fonctionnalités restent plus contraintes (p.ex. choix de types d’index, comportement des verrous, et certaines limites historiques autour du DDL online selon les cas).
Sur le plan des garanties transactionnelles, les deux proposent ACID, mais pas avec les mêmes compromis. PostgreSQL pousse très loin la cohérence et la visibilité des données via MVCC et une implémentation de l’isolation robuste (jusqu’à du SERIALIZABLE via SSI). MySQL/InnoDB vise un équilibre performant mais introduit des comportements subtils (gap locks, next-key locks) qui surprennent souvent les équipes quand la concurrence augmente (ex : panier/stock/réservations). Le résultat : le « meilleur » dépend moins du moteur que du profil de charge et de la discipline SQL (indexation, requêtes, transactions courtes).
Deux détails « structurels » qui ressortent souvent en exploitation (et qu’on sous-estime avant d’avoir vécu un incident) :
- Gestion des connexions : PostgreSQL crée typiquement un processus par connexion. En trafic web, on finit presque toujours par mettre un pool (ex. via un proxy de pool) pour éviter d’exploser en RAM et en context-switch. MySQL gère différemment ses threads, mais le problème « trop de connexions = latences et contention » reste réel côté application (surtout avec PHP-FPM + modules bavards).
- Extensibilité vs standardisation : PostgreSQL encourage l’extension (types, opérateurs, index spécialisés). C’est puissant… mais ça peut aussi vous lier à Postgres si vous bâtissez trop de logique « DB-native ». MySQL privilégie une trajectoire plus standard, parfois au prix de contournements applicatifs.
« PostgreSQL provides multiversion concurrency control (MVCC). » — Documentation PostgreSQL (chapitre MVCC) : Documentation PostgreSQL — MVCC
Performances : planificateur, indexation, JSON et partitionnement (ce qui se mesure réellement)
Le sujet performance en 2026 doit être cadré : sans protocole de test (données réalistes, requêtes réelles, métriques p95/p99, contention), toute conclusion « PostgreSQL est plus rapide que MySQL » (ou l’inverse) est du bruit. Sur une boutique PrestaShop, la perf perçue est dominée par le TTFB, la saturation PHP-FPM, le cache, puis la base. Avant d’optimiser le SGBD, vérifiez le socle (OPcache, pools, réseau, cache HTTP). Pour ce socle, vous avez déjà une base méthodologique côté MySQL : Performance PrestaShop : benchmarks et optimisation PHP-FPM, OPCache, MySQL et TTFB PrestaShop : réduire le Time To First Byte sous 200 ms.
Côté planificateur, PostgreSQL est généralement plus « agressif » sur les stratégies de jointure et l’exploitation de statistiques (avec une transparence excellente via EXPLAIN (ANALYZE, BUFFERS)), tandis que MySQL 8.x a énormément progressé mais reste plus dépendant d’heuristiques et de l’architecture InnoDB. En pratique : PostgreSQL brille souvent sur les requêtes analytiques « sales » (JOIN multiples, filtres composites, agrégations) si les statistiques sont à jour et que la mémoire (work_mem) est dimensionnée. MySQL reste très performant sur des patterns OLTP simples et très répétitifs, surtout quand le buffer pool InnoDB est bien dimensionné.
Pour rendre la comparaison mesurable, imposez un petit contrat de benchmark (même en interne) :
- Jeu de données : taille réaliste (catalogue, déclinaisons, attributs, commandes), distribution réaliste (peu de best-sellers + longue traîne).
- Mix requêtes : 70–90% lecture (catalogue, recherche, filtres), 10–30% écriture (paniers, commandes, logs), plus « batch » (imports/exports).
- Métriques : p50/p95/p99, taux d’erreurs/timeout, locks waits, IOPS, CPU, taille cache/buffer, et surtout stabilité quand on augmente la concurrence.
- Warm-up : cache chaud vs cache froid (les deux situations arrivent : redémarrage, failover, purge cache).
L’indexation est un point où la comparaison doit être concrète. MySQL/InnoDB s’appuie principalement sur des B-Tree (plus FULLTEXT et SPATIAL), et les gains sont souvent « binaires » : bon index = très bien, mauvais index = catastrophique. PostgreSQL offre une palette plus large (B-tree, Hash, GIN, GiST, BRIN) qui permet d’attaquer des cas d’usage spécifiques : recherche textuelle, tableaux, JSONB, similarité, données temporelles volumineuses. Sur MySQL, les functional indexes et l’évolution du support JSON rendent le moteur viable sur des données semi-structurées, mais PostgreSQL garde un avantage net sur les index GIN/JSONB dès que vous faites autre chose que des accès clé/valeur.
Exemple concret (fréquent en e-commerce) : recherche dans un champ JSON qui stocke des attributs produits ou des métadonnées de commande.
- En PostgreSQL,
jsonb+ index GIN peuvent accélérer des filtres sur la présence de clés, des recherches de valeurs, et des requêtes combinées. - En MySQL, JSON est très utilisable pour du stockage et des extractions, mais l’optimisation passe souvent par des colonnes générées/virtuelles + indexation ciblée (ce qui revient, dans les faits, à « re-schémer » ce qui doit être rapide).
Sur le partitionnement (souvent déclenché par l’historique de commandes/logs), retenez surtout une règle de production : le partitionnement n’est pas une optimisation automatique, c’est une stratégie de cycle de vie (archivage, purge, maintenance). Les deux moteurs savent partitionner, mais la simplicité opérationnelle varie selon vos requêtes, vos clés de partition et vos opérations de maintenance (purge mensuelle, conservation légale, exports). Dans un contexte PrestaShop, on partitionne rarement au départ ; on le fait quand l’historique devient une contrainte (backoffice lent, index qui explosent, sauvegardes trop longues).
« EXPLAIN displays the execution plan that the PostgreSQL planner generates for the supplied statement. » — Documentation PostgreSQL, commande EXPLAIN : Documentation PostgreSQL — EXPLAIN
Pour éviter les optimisations « au doigt mouillé », imposez une routine : EXPLAIN ANALYZE (PostgreSQL) / EXPLAIN ANALYZE (MySQL 8.x), capture des requêtes lentes, et itérations sur index + requêtes. Si votre production est MySQL (cas standard PrestaShop), commencez par industrialiser l’analyse d’index : Index MySQL : optimiser WHERE, JOIN et ORDER BY avec EXPLAIN. Pour PostgreSQL, activez pg_stat_statements dès le départ (sinon vous pilotez à l’aveugle).
Un rappel qui évite beaucoup de « faux problèmes SGBD » : avant d’ajouter un index, vérifiez (dans la requête) la cardinalité, la sélectivité, et l’ordre des conditions. En e-commerce, des conditions du type WHERE active = 1 ou WHERE shop_id = X sont rarement sélectives ; l’index utile est souvent un index composite qui colle à vos filtres réels (shop_id, active, date_add, etc.) et à vos tris (ORDER BY).
Concurrence et transactions : MVCC, verrous, deadlocks et gestion de stock
Le point qui sépare vraiment PostgreSQL vs MySQL en 2026, c’est le modèle de concurrence sous pression. PostgreSQL est MVCC « partout » : les lectures ne bloquent pas les écritures et inversement, tant que vous ne vous battez pas sur les mêmes lignes au même moment. En contrepartie, vous payez l’addition via le vacuum : si autovacuum est mal réglé (ou saturé), vous créez du bloat, de la latence I/O, et des régressions progressives. Autrement dit : PostgreSQL encaisse bien la concurrence, mais demande une hygiène d’exploitation stricte.
MySQL/InnoDB utilise aussi une forme de MVCC (consistent reads), mais le détail des verrous (row locks + gap/next-key locks selon le niveau d’isolation et les index) est une source classique d’incidents. Les symptômes e-commerce sont connus : montées de latence lors des soldes, deadlocks sur la table de stock, transactions qui s’étirent parce que le code applicatif ouvre une transaction trop tôt (ou fait du réseau au milieu). Dans PrestaShop, ces problèmes sont amplifiés par des modules qui bricolent des écritures en série (imports, synchronisations ERP, règles paniers) sans discipline transactionnelle.
Mini-scénario réaliste (pic de charge) :
- Un lot d’achats simultanés arrive sur un produit « rare ».
- Le code met à jour le stock, écrit un log, met à jour le panier, recalcule une règle promo, puis appelle un service externe (paiement / anti-fraude) avant de valider la transaction.
- Résultat : la transaction reste ouverte trop longtemps → les verrous s’accumulent → latences en cascade → timeouts côté front → re-try des clients → encore plus de contention.
Deux pratiques simples (valables dans les deux moteurs) réduisent drastiquement les incidents :
- Transactions courtes et « sans I/O réseau » : pas d’appel externe au milieu d’une transaction ; pas de traitement lourd tant que vous tenez des verrous.
- Écritures déterministes et ordonnées : si plusieurs tables doivent être modifiées, gardez un ordre constant (table A puis table B) pour réduire les cycles de deadlock.
Sur la gestion de stock, la base n’est souvent pas le bon endroit pour tout faire « en verrouillant ». Une stratégie pragmatique consiste à externaliser la contention sur une primitive atomique en mémoire (Redis) et à laisser la base jouer le rôle de source de vérité avec des transactions courtes. Ça évite de transformer votre SGBD en arbitre temps réel sur des pics de concurrence. Le pattern est détaillé ici : Performance e-commerce : prévenir la concurrence sur les stocks avec Redis. PostgreSQL et MySQL peuvent ensuite consommer des événements de réservation/confirmation, plutôt que de se battre en locks.
Un test simple à faire avant de trancher : prenez votre scénario critique (création commande + décrément stock + écriture logs + mise à jour panier), encapsulez-le dans une transaction stricte, et lancez un test de charge avec une montée progressive (50 → 500 → 2 000 req/min selon votre réalité). Mesurez : taux de deadlocks, latence p95, temps CPU, attente I/O, lock waits. Le moteur « gagnant » sera celui qui garde un comportement stable sous contention, pas celui qui a le meilleur résultat sur un micro-benchmark.
Enfin, si vous comparez réellement les deux moteurs sur ce point, faites attention à l’isolation transactionnelle : tester PostgreSQL en READ COMMITTED et MySQL en REPEATABLE READ (souvent le défaut) peut donner des comportements très différents sur les conflits. Documentez votre choix, car c’est un choix produit (cohérence vs débit) autant qu’un choix SGBD.
Sécurité : modèle de privilèges, chiffrement, audit et surface d’attaque
En sécurité, PostgreSQL et MySQL savent faire le minimum vital (TLS en transit, rôles, permissions, authentification robuste), mais l’ergonomie n’est pas la même. PostgreSQL est très fort sur la granularité SQL (roles, schemas, privileges), et surtout sur des mécanismes comme le Row Level Security (RLS) qui permet de filtrer des lignes au niveau serveur. En e-commerce multi-tenant (SaaS, multi-boutiques avec séparation forte), RLS peut simplifier une partie du contrôle d’accès — à condition de comprendre que vous déplacez une part de la logique d’autorisation dans la base, ce qui impose tests et revues de sécurité SQL.
MySQL est très utilisé dans des stacks web historiques ; le point faible typique n’est pas le moteur, mais l’écosystème : comptes partagés, droits trop larges, absence de séparation lecture/écriture, dumps non chiffrés, backups exposés, et logs SQL qui finissent dans des buckets sans contrôle. Si vous administrez une boutique PrestaShop, la priorité n°1 est rarement « changer de SGBD », mais « corriger l’hygiène » : séparation des privilèges, rotation des secrets, contrôle des accès réseau, durcissement du serveur. Pour un cadre orienté PrestaShop (WAF, journalisation, API backoffice), voir : Sécurité PrestaShop : protéger API backoffice, WAF et journalisation SIEM et Sécurité PrestaShop 2026 : risques majeurs et protections professionnelles.
Sur le chiffrement « at rest », les deux mondes se ressemblent en pratique : on s’appuie surtout sur le chiffrement disque (LUKS, EBS, etc.) et sur une gestion rigoureuse des clés/accès. PostgreSQL propose aussi du chiffrement côté applicatif et un contrôle fin des extensions, mais la réalité opérationnelle est que la sécurité dépend de vos runbooks (patching, backups testés, rotation).
Ajout important côté « GEO » (au sens conformité et localisation) pour des e-commerçants UE / France : la question n’est pas « Postgres vs MySQL », mais où sont stockées les données, qui y accède, et comment vous prouvez votre contrôle (journaux, traces d’accès, tests de restauration). Pour une boutique PrestaShop, les éléments qui reviennent en audit (internes ou clients B2B) sont souvent :
- politique de rétention (commandes, logs applicatifs, IP, consentement),
- séparation des environnements (prod / staging),
- chiffrement et contrôle d’accès des sauvegardes,
- preuve de restauration (RPO/RTO réalistes, exercice de restauration périodique).
Les CVE applicatives (modules, stack PHP) font plus de dégâts que les CVE base si votre exposition réseau est correcte ; exemple côté PrestaShop : CVE-2025-61922 ps_checkout : mise à jour 5.0.5 et mesures.
Exploitation : sauvegardes, réplication, HA, observabilité et coûts opérationnels
En prod, le « meilleur » SGBD est celui que vous savez opérer sans dette. PostgreSQL se pilote très bien avec des primitives claires : sauvegarde logique (pg_dump) pour des volumes raisonnables, sauvegarde physique + WAL pour du PITR (restauration à un point dans le temps), réplication streaming pour de la lecture et du failover. Mais PostgreSQL demande une vraie stratégie de maintenance : autovacuum correctement paramétré, surveillance du bloat, et tests de restauration réguliers. Sans ça, la perf se dégrade lentement, puis brutalement.
MySQL s’appuie sur un outillage mature : mysqldump (souvent trop lent au-delà d’un certain volume), hot backups via outils adaptés, réplication asynchrone très répandue, et des topologies HA (Group Replication / InnoDB Cluster) qui fonctionnent mais ajoutent de la complexité réseau et d’orchestration. Le point critique, sur des boutiques, est souvent la maintenance « silencieuse » : fragmentation, tables qui grossissent, index inutiles, et opérations DDL au mauvais moment. La routine de nettoyage et de maintenance est un vrai levier (et elle existe indépendamment du moteur) : Base de données PrestaShop : routine de maintenance et nettoyage automatisé.
Pour comparer les coûts opérationnels sans se mentir, listez noir sur blanc ce que vous exigez en production (et testez-le) :
- RPO/RTO : combien de données pouvez-vous perdre (RPO) et en combien de temps vous devez revenir (RTO) ?
- PITR : êtes-vous capables de restaurer « à 14:37 » après une suppression accidentelle ?
- Montées de version : fréquence, fenêtre, rollback, compatibilité applicative.
- Maintenance automatique : ce qui est « automatique mais pas magique » (vacuum côté Postgres, purge/optimisation côté MySQL, etc.).
- Coûts humains : astreinte, charge d’analyse incident, complexité du runbook.
L’observabilité est non négociable si vous voulez comparer PostgreSQL vs MySQL sérieusement. Fixez une baseline : saturation CPU, latence disque, buffer cache hit ratio, locks waits, top queries, connexions actives, temps de checkpoint, taille WAL/binlog, et temps de réplication. Sur PrestaShop, il faut corréler base + PHP + cache + front (sinon vous accusez le SGBD pour un problème applicatif). Le cadre « runbook + tests de charge + monitoring » est déjà posé ici : PrestaShop performance : monitoring, tests de charge et runbooks soldes. Adaptez-le en ajoutant les métriques spécifiques (PostgreSQL : pg_stat_activity, pg_stat_statements, WAL; MySQL : performance_schema, InnoDB metrics, replication lag).
Petit point terrain (souvent oublié) : la géographie de votre infra. Si vous êtes hébergé en France/UE avec plusieurs zones de disponibilité, la latence inter-zone et la qualité du stockage (IOPS/latence) peuvent dominer la différence Postgres/MySQL. Dans ce contexte, une « bonne » architecture (réplicas proches, stockage performant, pooling, caches) fait plus pour la stabilité qu’un changement de moteur.
Cas d’usage e-commerce et PrestaShop : quand rester sur MySQL, quand ajouter PostgreSQL
Point direct : le cœur de PrestaShop (8.x et 9.x à date) est conçu autour de MySQL/MariaDB. Le remplacer par PostgreSQL n’est pas une option « configuration » ; c’est un chantier de portage (requêtes SQL, DAL, schéma, tests) et un risque de compatibilité massif avec l’écosystème modules. Même si PrestaShop 9 a modernisé une partie du stack Symfony (voir PrestaShop 9 : nouveautés techniques Symfony 6.4, API et performances), la réalité terrain reste : beaucoup de code (core + modules) assume MySQL (syntaxe, fonctions, comportements de collation, INSERT ... ON DUPLICATE KEY, etc.). Pour une boutique existante, « migrer PrestaShop sur PostgreSQL » est généralement un anti-pattern.
En revanche, ajouter PostgreSQL à côté de MySQL est souvent rationnel. Cas d’usage fréquents en 2026 :
- Reporting/BI et requêtes analytiques : répliquer les données MySQL vers PostgreSQL (via CDC/Debezium ou réplication logique) pour faire tourner des agrégations et des exports lourds sans impacter l’OLTP.
- Recherche avancée et similarité : PostgreSQL avec
pg_trgmou full-text natif peut compléter (ou remplacer selon les cas) une stack Elasticsearch. Sur gros catalogues, l’option Elasticsearch reste pertinente : PrestaShop ElasticSearch : accélérer la recherche produit sur grands catalogues. - Event store / intégration : si vous construisez des services périphériques (pricing, OMS, synchronisation ERP) en Symfony/Doctrine, PostgreSQL est souvent un choix solide grâce à la qualité du SQL, des index et des migrations.
La stratégie « MySQL pour PrestaShop + PostgreSQL pour les workloads hors-core » réduit le risque applicatif tout en bénéficiant des forces de PostgreSQL. Typiquement : MySQL reste la source de vérité transactionnelle (commandes, paniers, clients), et PostgreSQL reçoit un flux de changements (CDC) pour alimenter dashboards, alertes, et calculs (cohortes, LTV, détection d’anomalies). Si vous avez déjà mis en place du cache (Varnish, Redis, OPcache), c’est cohérent avec une architecture qui sépare OLTP, cache et analytique : Cache PrestaShop : Varnish, Redis, Memcached et OPcache côté serveur.
Pour rendre ce choix plus « opérable », voici un mini-tableau de décision (orienté production) :
| Sujet | MySQL/MariaDB (PrestaShop core) | PostgreSQL (workloads complémentaires) |
|---|---|---|
| Compatibilité modules | Très forte (standard de fait) | Faible si vous voulez remplacer MySQL |
| Requêtes analytiques ad hoc | Possible, mais peut vite impacter l’OLTP | Souvent plus confortable (stats, plans, SQL riche) |
| Données semi-structurées | JSON utilisable, souvent via colonnes générées + index | JSONB + index GIN très puissant |
| Concurrence écriture complexe | Très bon, mais verrous InnoDB peuvent surprendre | MVCC robuste, à condition de maîtriser vacuum |
| Exploitation | Outillage très répandu en hébergement web | Runbooks spécifiques (WAL/PITR/vacuum/pooling) |
Avant de prendre une décision « PostgreSQL vs MySQL 2026 », utilisez une checklist orientée prod (pas un comparatif de features) :
- Profil de charge : plus de lectures simples (catalogue, pages) → MySQL + cache agressif tient très bien ; plus d’agrégations et de requêtes complexes côté backoffice/BI → PostgreSQL peut simplifier.
- Concurrence d’écriture : si vous subissez deadlocks/lock waits, vérifiez d’abord transactions trop longues et index manquants. Si le modèle de verrous InnoDB vous pénalise malgré corrections, PostgreSQL peut être plus stable — mais seulement si vous opérez correctement autovacuum.
- Compétences internes : équipe déjà à l’aise avec InnoDB, replication, tuning ? Ne sous-estimez pas le coût d’apprentissage PostgreSQL (WAL, vacuum, paramètres mémoire).
- Migrations : portage SQL (collations, types,
DATETIMEvsTIMESTAMP, JSON, upserts) et compatibilité modules PrestaShop : c’est le « mur » principal. - Plan de secours : quel est votre rollback si le projet dérive (retour MySQL, double écriture temporaire, freeze modules) ?
Enfin, faites une règle simple : si l’objectif est d’améliorer les perfs PrestaShop, commencez par l’indexation, la réduction des requêtes, le cache, et l’observabilité. Changer de SGBD sans avoir réglé ces points revient souvent à déplacer le problème (et à ajouter un risque de régression fonctionnelle) — et vous risquez de perdre du temps que vous auriez pu investir dans une approche méthodique (diagnostic, routine de maintenance, tests de charge, et durcissement).
