SQL performance : Postgres, MySQL ou SQLite, lequel choisir?

Postgres domine les requêtes analytiques complexes, MySQL excelle sur lectures simples et réplication, SQLite est idéal pour l’embarqué et le prototypage (pgbench, Percona, sqlite.org). Poursuivez pour méthodologie, résultats concrets et recommandations d’usage.

Quelle méthodologie de benchmark pour comparer ces moteurs

Une méthodologie rigoureuse compare moteur, dataset et charges réalistes en isolant l’environnement et en mesurant de façon standardisée (temps, CPU, I/O, plans d’exécution).

Contexte et objectifs — Comparer performances pour requêtes analytiques (joins, agrégations, group by), transactions OLTP et opérations d’écriture concurrentes. Ces catégories couvrent l’essentiel des usages : analyses lourdes sollicitent I/O et parallélisme, OLTP mesure latence et contention, écritures concurrentes révèlent gestion des verrous et WAL.

  • Dataset et scénarios — Trois tailles représentatives :
    • Petite : <100 MB (atteinte rapide du cache, CPU-bound).
    • Moyenne : ~10–50 GB (mix cache/I/O, réaliste pour PME).
    • Grande : >100 GB (I/O-bound, révèle besoin de partitionnement).
  • Schéma e‑commerce minimal — Tables users, products, orders, order_items avec index :
usersid PK, email UNIQUE, created_at; index sur email, created_at
productsid PK, sku UNIQUE, price, stock; index sur sku
ordersid PK, user_id FK, total, status, created_at; index(user_id, created_at)
order_itemsid PK, order_id FK, product_id FK, qty, price; index(order_id), index(product_id)
  • Environnement de test — Serveur type : 8–16 vCPU, 32–128 GB RAM, NVMe pour tests perf, comparer aussi HDD pour I/O limité.
  • Isolation — Désactiver swap, régler io scheduler (noop/none pour NVMe), isoler VM/serveur pour éviter noisy neighbors, répéter chaque test au moins 5 fois.
  • Outils et commandes — Exemples :
pgbench -i -s 50 mydb
pgbench -c 50 -j 4 -T 300 -P 10 --file=workload.sql mydb
sysbench oltp_read_write --threads=64 --time=300 --events=0 run
sqlite3 my.db "PRAGMA synchronous=OFF; PRAGMA journal_mode=WAL;" < queries.sql
  • Requêtes types — Joins multi‑table, GROUP BY avec SUM/COUNT, window functions (Postgres), bulk INSERT/COPY.
  • Métriques — Temps moyen, p95 latency, CPU%, I/O read/write (iotop/iostat), mémoire utilisée, plans (EXPLAIN/ANALYZE), locks et contention.
  • Validité — Documenter versions (Postgres, MySQL, SQLite), fichiers de config (postgresql.conf, my.cnf, PRAGMA), kernel/OS.

Résultat attendu — Table synthèse par moteur/workload : engine, workload, avg time, p95, commentaire, notes méthodologiques.

Inclure références vérifiables : documentation pgbench, Percona MySQL benchmarks, sqlite.org performance notes, et ne pas inventer de chiffres non mesurés.

Maîtrisez le No Code, l’IA Générative et la Data

Nos formations en No Code, IA Générative et Data sont pensées pour les professionnels qui veulent aller au-delà des tutoriels superficiels. Vous apprenez à modéliser vos processus, automatiser vos opérations (n8n, Make, Airtable), structurer vos données, et intégrer intelligemment l’IA dans vos workflows : génération de contenus, analyses accélérées, extraction d’informations, prototypes rapides.

Comment chaque moteur se comporte sur requêtes analytiques

Choix pragmatique selon les requêtes analytiques : chaque moteur a ses forces et ses limites — voici l’analyse pratique et chiffrée.

Postgres

  • Postgres est performant sur les agrégations complexes grâce à un planner cost sophistiqué, des types d’index riches (B‑tree, BRIN, GiST, GIN), et des algorithmes de jointure (hash/merge) optimisés pour grandes tailles de données.
  • Postgres implémente des fonctions analytiques (window functions) complètes et EXPLAIN ANALYZE renvoie des métriques précises d’exécution pour diagnostiquer CPU/IO.
  • Exemple EXPLAIN ANALYZE pour une jointure large et un GROUP BY :
HashAggregate  (cost=12345.67..12346.00 rows=1000) (actual time=345.67..345.90 rows=1000 loops=1)
  ->  Hash Join  (cost=2345.00..12300.00 rows=100000) (actual time=100.12..300.45 rows=100000 loops=1)
        Hash Cond: (a.id = b.a_id)
        -> Seq Scan on a
        -> Hash  (cost=2000.00..2000.01) (actual time=50.00..50.10 rows=100000 loops=1)
              -> Seq Scan on b

Interprétation : Hash Join indique distribution mémoire/CPU pour construire la table de hachage, HashAggregate montre agrégation en mémoire réduisant I/O si la mémoire suffit.

MySQL (InnoDB)

  • MySQL/InnoDB excelle en lecture simple et réplication grâce à l’optimisation pour workloads read‑heavy, index B‑tree stables et réplication asynchrone/GTID.
  • Optimiser MySQL est facilité par histogrammes d’optimizer (améliorent les choix de clé) mais les fonctionnalités analytiques (fenêtres) sont arrivées récemment et restent moins matures.
  • Exemple EXPLAIN (même requête) : montre souvent type=ref ou ALL, Using temporary; Using filesort indiquant tri/agrégation externes.

SQLite

  • SQLite est idéal pour embarqué, prototypes, ou lecture locale mono‑thread : démarrage instantané, zéro configuration, I/O sur disque local.
  • SQLite atteint ses limites sur très grosses tables et haute concurrence en raison du verrouillage au niveau de la page (même si WAL améliore la concurrence en lecture).

Concurrence et scalabilité

  • Postgres utilise MVCC (Multi‑Version Concurrency Control) permettant lectures non bloquantes et haute concurrence d’écritures si VACUUM est correctement paramétré.
  • InnoDB applique verrouillage au niveau de la ligne (row‑locking) mais peut subir lock escalations et performances variables sous fortes écritures concurrentes.
  • SQLite restreint concurrence par locking page‑level ; WAL aide, mais reste inadapté pour centaines de writers simultanés.
EngineAnalytical queriesBest caseWorst caseNotes opérationnelles
PostgresExcellent (joins, window, agg)Data warehouse OLAP, gros joinsContrainte mémoire mal configuréeTuner planner, maintenance (VACUUM/ANALYZE)
MySQL/InnoDBBon pour lectures simplesRead‑heavy, réplicationComplex analytics lourdsUtiliser histogrammes, optimiser indexes
SQLiteBasiqueEmbarqué, prototype mono‑threadTables massives, forte concurrenceWAL utile, pas pour scale‑out

Pour valider ces affirmations, mesurer avec pgbench/pg docs, analyses Percona pour MySQL, et la documentation sqlite.org est indispensable : https://www.postgresql.org/docs/, https://www.percona.com/blog/, https://www.sqlite.org/docs.html.

Conclure par des mesures : Les observations doivent provenir des benchmarks et EXPLAIN ANALYZE définis précédemment (latence, débit, IO, CPU, locks) pour tirer la décision opérationnelle.

Quelles optimisations pratiques pour améliorer les performances

Pour gagner du temps et du CPU, ajuster la configuration serveur, l’indexation et analyser les plans de requêtes fournit le plus grand gain ; chaque moteur a ses leviers (Postgres : work_mem/shared_buffers ; MySQL : innodb_buffer_pool_size ; SQLite : WAL/journal_mode).

  • Indexation et requêtes — Privilégier des index composites quand la même colonne sert pour les filtres et les tris, et des index dit "covering" quand toutes les colonnes d’une requête sont dans l’index.
  • Bonnes pratiques — Créer des index pour joins et GROUP BY seulement si la sélection/agrégation est fréquente et coûteuse ; supprimer les index non utilisés pour accélérer les écritures.
-- Index pour JOIN (Postgres & MySQL)
CREATE INDEX idx_orders_customer ON orders (customer_id, created_at);

-- Index couvrant en Postgres (INCLUDE rend l'index couvrant)
CREATE INDEX idx_sales_prod_date ON sales (product_id, sale_date) INCLUDE (amount);
  • Paramètres serveurs — Postgres :

Shared_buffers = 25% RAM recommandée. Effective_cache_size = 50-75% RAM pour le planificateur. Work_mem = mémoire par opération de tri/hash (exemple : sur 16GB RAM → shared_buffers=4GB, effective_cache_size=12GB, work_mem=16MB, maintenance_work_mem=512MB ; sur 64GB RAM → shared_buffers=16GB, effective_cache_size=48GB, work_mem=64MB, maintenance_work_mem=2GB). Autovacuum doit être actif pour éviter bloat.

MySQL/InnoDB :

Innodb_buffer_pool_size = 60-80% RAM sur serveur DB dédié. Innodb_flush_log_at_trx_commit = 1 (sécurité), 2 (compromis), 0 (performance). Innodb_io_capacity ajusté selon le stockage (HDD ~200, SSD ~2000).

SQLite :

PRAGMA journal_mode = WAL ; PRAGMA synchronous = NORMAL ; PRAGMA cache_size = 2000 ; Ces réglages améliorent concurrence et latence en écriture.

  • Maintenance — Postgres/SQLite : VACUUM et ANALYZE réguliers. MySQL : OPTIMIZE TABLE et ANALYZE TABLE.
  • Architecture — Partitioning (range/hash) pour tables massives, sharding basique pour montée en charge, et réplicas en lecture seule pour délester le primaire.
-- Commandes de bench et maintenance
pgbench -i -s 10 mydb
pgbench -c 10 -j 2 -T 60 mydb

sysbench oltp_read_write --threads=8 --time=60 run

sqlite3 my.db "PRAGMA journal_mode=WAL; PRAGMA synchronous=NORMAL; PRAGMA cache_size=2000;"

VACUUM;
ANALYZE;
OPTIMIZE TABLE mytable;
ANALYZE TABLE mytable;
OptimisationMoteurImpact attenduComplexité
Index composite / coveringPostgres / MySQLLecture & agrégations beaucoup plus rapidesMoyenne
shared_buffers / buffer_poolPostgres / MySQLMoindre I/O disque, meilleures latencesMoyenne
WAL & synchronousSQLiteMeilleure concurrence d'écritureFaible
VACUUM / OPTIMIZETousRéduit la fragmentation, plans plus fiablesFaible
Partitioning / RéplicationPostgres / MySQLScalabilité horizontale importanteÉlevée

Valider chaque réglage en mesurant avant/après avec pgbench/sysbench/sqlite PRAGMA et en surveillant CPU, I/O, latence et plans d'exécution.

Comment choisir le moteur adapté à votre projet

Choisir un moteur SQL se fait en fonction de vos besoins fonctionnels : complexité analytique, volume, concurrence, contraintes opérationnelles et coût d’exploitation.

1) Critères de choix

  • Taille Des Données : Quelques Mo/Go → SQLite. Plusieurs To → Postgres ou entrepôt dédié.
  • Connexions Concurrentes : Peu (embedded) → SQLite. Milliers de connexions → Postgres/MySQL avec pool.
  • Exigences ACID : Transactions strictes et isolation → Postgres (référence : https://www.postgresql.org/docs/).
  • Fonctionnalités Analytiques : Fenêtres, CTEs, fonctions avancées → Postgres > MySQL 8 > SQLite.
  • Hébergement / Cloud : Besoin de managed services → MySQL/Postgres (RDS, Cloud SQL, Aurora).
  • Expertise Opérationnelle : Coût humain pour backups, HA, tuning.

2) Cartographie use‑case → moteur

  • Petite App Embarquée : SQLite. Justification : zéro administration, fichier unique.
  • Site Web Read‑Heavy : MySQL si architecture LAMP et besoin simple de réplication ; Postgres si requêtes complexes et intégrité forte.
  • Entrepôt Analytique : Postgres (ou solution dédiée OLAP) pour optimisations de requêtes et extensions.
  • Prototype Local : SQLite pour vitesse de démarrage ; bascule vers Postgres en production.

3) Checklist pratique

  • Prévision De Croissance, SLA Attendus, RTO/RPO pour DR, Stratégie De Backups, Observabilité (logs, métriques), Plan De Migration.

4) Exemples concrets

  • App Mobile (Dataset 200MB, SLA faible, Budget minimal) → SQLite.
  • E‑commerce (Dataset 200GB, 50 writes/s peak, SLA 99.95%) → Postgres (transactions, réplication, backups).
  • Analytics (Dataset 2TB, requêtes complexes, SLA tolérant latence) → Postgres + entrepôt ou extensions columnar.

5) Tableau synthèse final

Use CaseRecommended EngineWhyOps Complexity
Embedded AppSQLiteZero administration, fichier uniqueLow
Read‑heavy WebMySQLSimple réplication, écosystème LAMPMedium
Transactional / Complex QueriesPostgresACID, fonctions analytiquesHigh

6) Appel à l’action

Prototyper rapidement, lancer des tests de charge (pgbench/sysbench), valider sauvegardes et failover, mesurer latence et coûts. Voir docs : https://www.postgresql.org/docs/, https://dev.mysql.com/doc/, https://www.sqlite.org/docs.html.

Prêt à choisir le moteur adapté à votre projet ?

En synthèse, le meilleur moteur dépend de vos priorités : Postgres pour l’analytique et la richesse fonctionnelle, MySQL pour des architectures web read‑heavy et une réplication simple, SQLite pour l’embarqué et le prototypage. La décision doit découler de tests reproductibles (pgbench/sysbench/sqlite PRAGMA), d’un inventaire des contraintes opérationnelles et d’un plan de tuning progressif. En vous appuyant sur la méthodologie et les optimisations présentées, vous réduirez le risque d’erreur et gagnerez en performance mesurable — bénéfice direct : plus de stabilité et de rapidité pour vos usages réels.

FAQ

Quel moteur est le plus rapide en général pour l’analytique ?

Postgres montre généralement les meilleures performances sur requêtes analytiques complexes grâce à son planner, types d’index et fonctions avancées, mais tout dépend de la charge et du tuning mesuré via des benchmarks.

SQLite peut‑il remplacer Postgres en production ?

SQLite convient pour applications mono‑utilisateur, embarquées ou prototypes. Il n’est pas adapté aux charges concurrentes élevées ni aux gros entrepôts de données en production multi‑utilisateurs.

Comment reproduire rapidement les benchmarks ?

Utilisez pgbench pour Postgres, sysbench pour MySQL et scripts sqlite3 avec PRAGMA pour SQLite ; isolez l’environnement, répétez les tests et collectez p95, CPU, I/O et plans EXPLAIN pour chaque requête.

Quelles optimisations donnent le meilleur ROI ?

Indexation adaptée et réglage mémoire (shared_buffers/work_mem pour Postgres, innodb_buffer_pool_size pour MySQL) fournissent souvent les gains les plus rapides ; mesurer avant/après reste indispensable.

Faut‑il choisir un moteur selon l’hébergement cloud ?

Oui : considérations opérationnelles (managed services, sauvegardes, réplication) peuvent orienter le choix. Postgres et MySQL disposent d’offres managées robustes ; SQLite n’est pas conçu pour les services managés multi‑tenant.

 

 

A propos de l'auteur

Franck Scandolera — Expert & formateur en Tracking server‑side, Analytics Engineering, Automatisation No/Low Code (n8n) et intégration IA en entreprise. Responsable de l’agence webAnalyste et de l’organisme de formation "Formations Analytics". Référence clients : Logis Hôtel, Yelloh Village, BazarChic, Fédération Française de Football, Texdecor. Dispo pour aider les entreprises => contactez moi.

Retour en haut
Formations Analytics