Le volume croissant des données impose d’adapter constamment les infrastructures logicielles. Un choix inadapté dégrade les performances et génère des latences inacceptables. Dans ce contexte, l’arbitrage entre DuckDB et PostgreSQL pose la question d’adopter un moteur OLAP en colonnes pour l’analytique. Cette décision s’avère cruciale pour éviter d’importants surcoûts matériels aux entreprises.
Cet article livre une analyse technique détaillée pour comparer leurs architectures de stockage. Il fournit des critères clairs afin de distinguer l’opérationnel de la charge analytique. L’étude de divers cas concrets facilite l’intégration technique d’un modèle orienté en colonnes. Le but final reste d’identifier l’outil le plus adéquat selon votre topologie de données.
Architecture et philosophie : PostgreSQL face à DuckDB
PostgreSQL suit une architecture client-serveur : l’application dialogue avec un serveur de base de données séparé, local ou distant, capable de gérer de nombreuses connexions simultanées. Cette séparation ajoute un aller-retour entre le client et le moteur, particulièrement visible lorsque les échanges sont très fréquents. DuckDB fonctionne au contraire comme une bibliothèque embarquée directement dans le processus de l’application. Pour des données locales, ce modèle évite la couche réseau et réduit fortement les coûts de transfert entre l’application et le moteur SQL.
PostgreSQL privilégie le traitement transactionnel rapide de lignes individuelles (OLTP). Il garantit la cohérence des opérations critiques des applications web. DuckDB se consacre à l’analyse massive de données en colonnes (OLAP). Sa spécialisation optimise les agrégations mais pénalise les écritures fréquentes.
Ces divergences d’architecture guident le choix selon les usages cibles. PostgreSQL s’impose comme le socle idéal des systèmes opérationnels complexes. DuckDB convient parfaitement à l’analyse locale et la science des données. Son intégration directe évite tout déploiement d’infrastructure réseau dédiée.
Organisation du stockage : modèle en lignes contre modèle en colonnes
PostgreSQL utilise un stockage orienté lignes en regroupant les enregistrements dans des pages de 8 kilooctets. Ce format optimise les transactions en écrivant un tuple complet en une seule opération disque. Cependant, le balayage de tables larges contraint le moteur à charger l’intégralité des colonnes inutiles. Ce gaspillage de bande passante et de mémoire pénalise fortement les calculs analytiques.
DuckDB privilégie un stockage orienté colonnes où les données d’une même nature sont regroupées séquentiellement. Ce modèle permet l’élagage des entrées-sorties en lisant uniquement les attributs sollicités par la requête. Les colonnes superflues sont ainsi quasiment ignorées lors de l’exécution. Cette approche ciblée préserve la bande passante et accélère le traitement des données.
L’homogénéité des données par colonne autorise également des mécanismes de compression très agressifs. Des algorithmes comme l’encodage RLE ou par dictionnaire réduisent considérablement l’empreinte disque. La diminution du volume physique accélère directement les transferts vers la mémoire vive. Ces optimisations confèrent à DuckDB une efficacité accrue sur les requêtes d’agrégation.
Mécanismes d’exécution analytique et traitement OLAP
Le moteur d’exécution historique de PostgreSQL repose largement sur un modèle tuple-at-a-time : les opérateurs produisent les lignes au fil de l’exécution, même si PostgreSQL dispose aussi de mécanismes de parallélisation pour certaines requêtes. DuckDB a été conçu autour d’un moteur vectorisé qui traite les données par vecteurs de 2 048 valeurs. Ce traitement par lots réduit la surcharge liée aux appels répétés entre opérateurs et améliore la localité mémoire sur les charges analytiques.
Cette architecture vectorisée permet au moteur d’exploiter efficacement les caches processeur et, lorsque les opérateurs s’y prêtent, les instructions SIMD (Single Instruction, Multiple Data). Plusieurs valeurs peuvent alors être traitées avec une même opération bas niveau. Le gain ne vient donc pas d’une seule optimisation matérielle, mais de la combinaison entre traitement par lots, meilleure localité mémoire et code spécialisé pour les charges analytiques.
Pour les agrégations, jointures et regroupements massifs, DuckDB utilise des structures de données et des algorithmes pensés pour l’analytique vectorisée. PostgreSQL peut lui aussi paralléliser certaines requêtes et déverser sur disque les opérations qui dépassent la mémoire disponible, notamment lorsque work_mem est insuffisant. DuckDB dispose également de mécanismes de spill-to-disk : son avantage tient surtout à une architecture conçue dès l’origine pour scanner et agréger de gros volumes de façon efficace, et non à l’absence totale d’entrées-sorties temporaires.
Garanties ACID et gestion de la concurrence transactionnelle
PostgreSQL offre des garanties ACID complètes grâce à son mécanisme MVCC. Ce système gère les accès simultanés en limitant fortement les blocages entre lectures et écritures. Son journal de réécriture en amont (WAL) sécurise les transactions et garantit une restauration fiable en cas de panne. Cette robustesse en fait la référence pour les applications transactionnelles critiques.
DuckDB assure lui aussi des transactions ACID, mais son architecture vise d’abord les traitements analytiques et les écritures par lots. Il sait effectuer des INSERT, UPDATE et DELETE, mais il n’est pas conçu pour absorber en permanence une très grande quantité de petites transactions concurrentes comme un serveur OLTP. Pour alimenter de gros jeux de données, les insertions par lots et les chargements depuis des fichiers restent généralement plus adaptés que des écritures unitaires répétées.
Ces choix d’architecture définissent aussi la gestion de la concurrence. PostgreSQL a été conçu pour servir de nombreux clients et transactions simultanés grâce à son architecture serveur et à son MVCC. DuckDB permet plusieurs threads lecteurs et écrivains au sein d’un même processus, avec contrôle des conflits, mais son modèle embarqué n’a pas été pensé comme un serveur multi-clients destiné à une avalanche de transactions indépendantes. La principale différence porte donc sur le type de concurrence visé, plus que sur une opposition simpliste entre un seul écrivain et plusieurs lecteurs.
Scénarios métiers privilégiant un stockage orienté colonnes
DuckDB simplifie les pipelines de données grâce à une approche Zero-ETL. Il interroge directement des fichiers Parquet, Arrow, JSON ou CSV sans chargement dans des tables physiques. Son moteur lit ces sources brutes à la volée tout en maintenant d’excellentes performances SQL. Cette approche élimine des étapes d’importation souvent coûteuses et chronophages.
Cette capacité s’étend au cloud, notamment sur Amazon S3 et Google Cloud Storage. Via des requêtes HTTP Range, DuckDB télécharge principalement les métadonnées et fragments utiles au calcul. Il évite ainsi le transfert inutile de volumes massifs sur le réseau. L’exploration d’un Data Lake s’effectue sans déployer de clusters complexes.
L’outil s’intègre étroitement à l’écosystème Python, notamment avec Pandas, Polars et Apache Arrow. Selon les formats et les opérations, cette interopérabilité peut éviter certaines copies de données, sans pour autant garantir un fonctionnement zéro-copie dans tous les cas. DuckDB sait aussi exécuter de nombreuses opérations en mode out-of-core en utilisant le disque lorsque les données intermédiaires dépassent la mémoire disponible. Cette capacité permet de traiter des volumes supérieurs à la RAM, même si certaines requêtes ou certains paramètres peuvent encore conduire à une erreur de mémoire.
Analyse des performances selon le profil des requêtes
PostgreSQL reste particulièrement adapté aux opérations CRUD répétées et aux recherches très sélectives dans une application transactionnelle. Ses index B-Tree et les autres types d’index permettent de cibler rapidement quelques lignes tout en conservant une forte concurrence entre utilisateurs. DuckDB possède lui aussi des mécanismes d’élagage comme les zonemaps et peut utiliser des index ART pour certaines recherches très sélectives. Il n’est donc pas condamné au balayage complet d’une table, mais son architecture globale reste moins adaptée qu’un SGBD OLTP à une succession permanente de petites lectures et écritures concurrentes.
La situation peut s’inverser lors des calculs statistiques, des scans de grandes tables et des analyses complexes. Sur ce type de workload, DuckDB peut être plusieurs fois plus rapide que PostgreSQL, voire dépasser un ordre de grandeur dans certains benchmarks. Il n’existe toutefois aucun multiplicateur universel : le résultat dépend de la requête, du schéma, des index, du format des données, du matériel et de la configuration des deux moteurs. L’avantage structurel de DuckDB vient notamment de son exécution vectorisée et de sa capacité à ne lire que les colonnes utiles.
Sur les charges analytiques qui balayent une grande partie d’une table, le stockage orienté lignes de PostgreSQL peut conduire à lire davantage de données qu’un moteur colonnaire, surtout lorsque seules quelques colonnes sont nécessaires. PostgreSQL dispose néanmoins d’un optimiseur mature, d’index, du partitionnement et de l’exécution parallèle, qui peuvent réduire fortement cet écart selon la requête. DuckDB conserve un avantage architectural pour les scans et agrégations massifs, tandis que PostgreSQL reste beaucoup plus polyvalent pour les applications transactionnelles.
Évaluation des contraintes d’infrastructure et d’exploitation
PostgreSQL demande davantage d’exploitation qu’un moteur embarqué, mais cette charge varie fortement selon le contexte. PgBouncer peut être utile lorsque le nombre de connexions devient élevé, sans être obligatoire dans tous les déploiements. Le mécanisme VACUUM est indispensable au fonctionnement du MVCC, mais il est normalement pris en charge automatiquement par autovacuum. Quant à la haute disponibilité, elle peut exiger une expertise spécifique en auto-hébergement, tandis que les offres PostgreSQL managées automatisent une grande partie de ces tâches.
À l’opposé, DuckDB adopte principalement une architecture embarquée sans serveur à administrer séparément. Il s’intègre comme une dépendance logicielle et réduit fortement les tâches classiques de gestion des connexions, de déploiement et de maintenance d’un service de base de données. Cette simplicité constitue un avantage majeur pour l’analyse locale, les notebooks, les pipelines et les applications embarquant directement leur moteur analytique.
Ces divergences déplacent la responsabilité opérationnelle au sein du système. PostgreSQL prend en charge la persistance globale et la concurrence multi-utilisateurs. DuckDB délègue quant à lui la sauvegarde et l’organisation des fichiers au développeur. L’arbitrage repose donc entre un service distant et un moteur intégré.
Synergies et architectures hybrides en environnement de production
Les architectures modernes privilégient une séparation nette entre flux transactionnels et analytiques. PostgreSQL y tient le rôle de base opérationnelle pour valider les données métiers en temps réel. Les informations chaudes sont ensuite exportées de façon asynchrone au format Parquet vers un stockage objet. Cette isolation préserve l’application principale des surcharges créées par le reporting.
DuckDB intervient en aval pour exécuter les calculs complexes hors de la base principale. Son extension postgres permet d’interroger directement une instance PostgreSQL active. Il devient ainsi aisé de croiser les historiques froids sur S3 avec les données chaudes de production. Cette interopérabilité limite les copies superflues et fluidifie les flux analytiques.
L’association d’outils comme dbt à dbt-duckdb facilite la création de datamarts légers et performants. Ce modèle hybride allie la robustesse transactionnelle de PostgreSQL à la vitesse analytique de DuckDB. Chaque moteur agit dans son domaine de prédilection sans solliciter l’autre. L’entreprise déploie ainsi un système décisionnel véloce tout en maîtrisant ses coûts d’infrastructure.
Arbre de décision pour le choix d’un moteur de données
Passer à un moteur colonnaire devient pertinent lorsque la majorité du workload consiste à scanner, filtrer, joindre et agréger de nombreux enregistrements, surtout si seules quelques colonnes sont nécessaires et si les données changent peu entre deux analyses. Il n’existe pas de seuil universel en gigaoctets : une petite base peut déjà bénéficier de DuckDB si les requêtes sont analytiques, tandis qu’une très grosse base PostgreSQL peut rester adaptée si les accès sont essentiellement transactionnels. L’interrogation directe de fichiers Parquet constitue également un atout décisif pour les pipelines et les Data Lakes.
À l’inverse, PostgreSQL reste généralement le meilleur choix lorsqu’une application doit gérer de nombreuses transactions concurrentes, des écritures fréquentes, des contraintes d’intégrité complexes et des recherches unitaires à faible latence. Son architecture OLTP, son MVCC, ses index et son modèle client-serveur répondent précisément à ce type de besoin. DuckDB peut effectuer ces opérations, mais elles ne constituent pas son terrain de prédilection.
L’arbitrage repose donc moins sur la taille brute de la base que sur le profil des requêtes. PostgreSQL excelle comme base opérationnelle multi-utilisateurs ; DuckDB excelle lorsqu’il faut analyser rapidement de gros ensembles de données, notamment des fichiers Parquet ou des exports issus du système transactionnel. Les deux outils ne sont pas nécessairement concurrents : dans de nombreuses architectures, PostgreSQL stocke et sécurise les données chaudes pendant que DuckDB prend en charge les calculs analytiques lourds. Le meilleur choix consiste alors à utiliser chaque moteur dans le domaine pour lequel il a été conçu.
- Partager l'article :

