[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-28-pipeline-donnees-haut-debit-insertions-lots":3},{"article":4,"author":59},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":24,"related_articles":39},"d6000000-0000-0000-0000-000000000128","a0000000-0000-0000-0000-000000000065","Deep EVM #28 : Pipeline de données haut débit — Insertions par lots, COPY et résolution de conflits","deep-evm-28-pipeline-donnees-haut-debit-insertions-lots","Construisez des pipelines de données haut débit avec PostgreSQL en utilisant le protocole COPY, les patterns d'upsert en masse, le réglage WAL, le pooling de connexions PgBouncer et le monitoring.","## Le défi du haut débit\n\nConstruire un indexeur blockchain qui traite des millions de blocs nécessite d'insérer des milliards de lignes aussi vite que possible. Les instructions INSERT individuelles plafonnent à 5 000 lignes par seconde ; le protocole COPY pousse à 250 000+ lignes par seconde. Cet article couvre les techniques qui font la différence.\n\n## INSERT par lots\n\nLa première optimisation : regrouper les insertions :\n\n```rust\n\u002F\u002F Au lieu de :\nfor row in rows {\n    sqlx::query(\"INSERT INTO events (id, data) VALUES ($1, $2)\")\n        .bind(&row.id)\n        .bind(&row.data)\n        .execute(&pool)\n        .await?;\n}\n\n\u002F\u002F Utilisez l'insertion par lots :\nlet mut builder = sqlx::QueryBuilder::new(\n    \"INSERT INTO events (id, data) \"\n);\nbuilder.push_values(rows.iter().take(1000), |mut b, row| {\n    b.push_bind(&row.id)\n     .push_bind(&row.data);\n});\nbuilder.build().execute(&pool).await?;\n```\n\nPerformance : 5 000 rows\u002Fs -> 50 000 rows\u002Fs (10x).\n\n## Le protocole COPY\n\nCOPY est le mécanisme le plus rapide pour charger des données dans PostgreSQL :\n\n```rust\nuse tokio_postgres::CopyInWriter;\n\nlet writer = client.copy_in(\n    \"COPY events (id, block_number, data) FROM STDIN WITH (FORMAT BINARY)\"\n).await?;\n\nlet mut writer = BinaryCopyInWriter::new(writer, &[Type::INT8, Type::INT8, Type::JSONB]);\n\nfor row in rows {\n    writer.write(&[&row.id, &row.block_number, &row.data]).await?;\n}\n\nwriter.finish().await?;\n```\n\nPerformance : 50 000 rows\u002Fs -> 250 000+ rows\u002Fs (5x supplémentaire).\n\n## Upsert en masse avec ON CONFLICT\n\n```sql\nINSERT INTO accounts (address, balance, updated_at)\nSELECT * FROM UNNEST($1::text[], $2::numeric[], $3::timestamptz[])\nON CONFLICT (address)\nDO UPDATE SET\n    balance = EXCLUDED.balance,\n    updated_at = EXCLUDED.updated_at\nWHERE accounts.updated_at \u003C EXCLUDED.updated_at;\n```\n\nLa clause WHERE empêche les mises à jour obsolètes — essentiel quand les données arrivent dans le désordre.\n\n## Réglage WAL\n\nLe Write-Ahead Log (WAL) est le goulot d'étranglement pour les écritures à haut débit :\n\n```sql\n-- postgresql.conf\nwal_level = minimal          -- Réduire le logging WAL (pas de réplication)\nmax_wal_size = 4GB           -- Buffer WAL plus grand avant checkpoint\ncheckpoint_completion_target = 0.9  -- Étaler les checkpoints\nsynchronous_commit = off     -- Acquitter avant flush disque\n```\n\nAttention : `synchronous_commit = off` peut perdre les dernières millisecondes de données en cas de crash. Acceptable pour les indexeurs qui peuvent réindexer.\n\n## Pooling de connexions avec PgBouncer\n\n```ini\n# pgbouncer.ini\n[databases]\nmydb = host=127.0.0.1 dbname=mydb\n\n[pgbouncer]\npool_mode = transaction\nmax_client_conn = 1000\ndefault_pool_size = 50\n```\n\nPgBouncer multiplex les connexions : 1000 connexions application -> 50 connexions PostgreSQL. Cela réduit l'overhead de gestion de connexions et permet plus de concurrence.\n\n## Monitoring avec pg_stat_statements\n\n```sql\n-- Top 10 des requêtes par temps total\nSELECT\n    query,\n    calls,\n    round(total_exec_time::numeric, 2) AS total_ms,\n    round(mean_exec_time::numeric, 2) AS mean_ms,\n    rows\nFROM pg_stat_statements\nORDER BY total_exec_time DESC\nLIMIT 10;\n```\n\n## Résultats\n\n| Technique | Débit | Amélioration |\n|-----------|-------|--------------|\n| INSERT unitaire | 5K rows\u002Fs | Base |\n| INSERT par lots (1000) | 50K rows\u002Fs | 10x |\n| COPY binaire | 250K rows\u002Fs | 50x |\n| COPY + WAL tuning | 400K rows\u002Fs | 80x |\n\n## Conclusion\n\nLes pipelines de données haut débit avec PostgreSQL reposent sur le protocole COPY pour le chargement, l'upsert en masse pour l'idempotence, le réglage WAL pour le débit d'écriture et PgBouncer pour le pooling de connexions. Ensemble, ces techniques permettent de traiter des centaines de milliers de lignes par seconde.","\u003Ch2 id=\"le-d-fi-du-haut-d-bit\">Le défi du haut débit\u003C\u002Fh2>\n\u003Cp>Construire un indexeur blockchain qui traite des millions de blocs nécessite d’insérer des milliards de lignes aussi vite que possible. Les instructions INSERT individuelles plafonnent à 5 000 lignes par seconde ; le protocole COPY pousse à 250 000+ lignes par seconde. Cet article couvre les techniques qui font la différence.\u003C\u002Fp>\n\u003Ch2 id=\"insert-par-lots\">INSERT par lots\u003C\u002Fh2>\n\u003Cp>La première optimisation : regrouper les insertions :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">\u002F\u002F Au lieu de :\nfor row in rows {\n    sqlx::query(\"INSERT INTO events (id, data) VALUES ($1, $2)\")\n        .bind(&amp;row.id)\n        .bind(&amp;row.data)\n        .execute(&amp;pool)\n        .await?;\n}\n\n\u002F\u002F Utilisez l'insertion par lots :\nlet mut builder = sqlx::QueryBuilder::new(\n    \"INSERT INTO events (id, data) \"\n);\nbuilder.push_values(rows.iter().take(1000), |mut b, row| {\n    b.push_bind(&amp;row.id)\n     .push_bind(&amp;row.data);\n});\nbuilder.build().execute(&amp;pool).await?;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Performance : 5 000 rows\u002Fs -&gt; 50 000 rows\u002Fs (10x).\u003C\u002Fp>\n\u003Ch2 id=\"le-protocole-copy\">Le protocole COPY\u003C\u002Fh2>\n\u003Cp>COPY est le mécanisme le plus rapide pour charger des données dans PostgreSQL :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">use tokio_postgres::CopyInWriter;\n\nlet writer = client.copy_in(\n    \"COPY events (id, block_number, data) FROM STDIN WITH (FORMAT BINARY)\"\n).await?;\n\nlet mut writer = BinaryCopyInWriter::new(writer, &amp;[Type::INT8, Type::INT8, Type::JSONB]);\n\nfor row in rows {\n    writer.write(&amp;[&amp;row.id, &amp;row.block_number, &amp;row.data]).await?;\n}\n\nwriter.finish().await?;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Performance : 50 000 rows\u002Fs -&gt; 250 000+ rows\u002Fs (5x supplémentaire).\u003C\u002Fp>\n\u003Ch2 id=\"upsert-en-masse-avec-on-conflict\">Upsert en masse avec ON CONFLICT\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-sql\">INSERT INTO accounts (address, balance, updated_at)\nSELECT * FROM UNNEST($1::text[], $2::numeric[], $3::timestamptz[])\nON CONFLICT (address)\nDO UPDATE SET\n    balance = EXCLUDED.balance,\n    updated_at = EXCLUDED.updated_at\nWHERE accounts.updated_at &lt; EXCLUDED.updated_at;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>La clause WHERE empêche les mises à jour obsolètes — essentiel quand les données arrivent dans le désordre.\u003C\u002Fp>\n\u003Ch2 id=\"r-glage-wal\">Réglage WAL\u003C\u002Fh2>\n\u003Cp>Le Write-Ahead Log (WAL) est le goulot d’étranglement pour les écritures à haut débit :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">-- postgresql.conf\nwal_level = minimal          -- Réduire le logging WAL (pas de réplication)\nmax_wal_size = 4GB           -- Buffer WAL plus grand avant checkpoint\ncheckpoint_completion_target = 0.9  -- Étaler les checkpoints\nsynchronous_commit = off     -- Acquitter avant flush disque\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Attention : \u003Ccode>synchronous_commit = off\u003C\u002Fcode> peut perdre les dernières millisecondes de données en cas de crash. Acceptable pour les indexeurs qui peuvent réindexer.\u003C\u002Fp>\n\u003Ch2 id=\"pooling-de-connexions-avec-pgbouncer\">Pooling de connexions avec PgBouncer\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-ini\"># pgbouncer.ini\n[databases]\nmydb = host=127.0.0.1 dbname=mydb\n\n[pgbouncer]\npool_mode = transaction\nmax_client_conn = 1000\ndefault_pool_size = 50\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>PgBouncer multiplex les connexions : 1000 connexions application -&gt; 50 connexions PostgreSQL. Cela réduit l’overhead de gestion de connexions et permet plus de concurrence.\u003C\u002Fp>\n\u003Ch2 id=\"monitoring-avec-pg-stat-statements\">Monitoring avec pg_stat_statements\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-sql\">-- Top 10 des requêtes par temps total\nSELECT\n    query,\n    calls,\n    round(total_exec_time::numeric, 2) AS total_ms,\n    round(mean_exec_time::numeric, 2) AS mean_ms,\n    rows\nFROM pg_stat_statements\nORDER BY total_exec_time DESC\nLIMIT 10;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"r-sultats\">Résultats\u003C\u002Fh2>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Technique\u003C\u002Fth>\u003Cth>Débit\u003C\u002Fth>\u003Cth>Amélioration\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>INSERT unitaire\u003C\u002Ftd>\u003Ctd>5K rows\u002Fs\u003C\u002Ftd>\u003Ctd>Base\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>INSERT par lots (1000)\u003C\u002Ftd>\u003Ctd>50K rows\u002Fs\u003C\u002Ftd>\u003Ctd>10x\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>COPY binaire\u003C\u002Ftd>\u003Ctd>250K rows\u002Fs\u003C\u002Ftd>\u003Ctd>50x\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>COPY + WAL tuning\u003C\u002Ftd>\u003Ctd>400K rows\u002Fs\u003C\u002Ftd>\u003Ctd>80x\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch2 id=\"conclusion\">Conclusion\u003C\u002Fh2>\n\u003Cp>Les pipelines de données haut débit avec PostgreSQL reposent sur le protocole COPY pour le chargement, l’upsert en masse pour l’idempotence, le réglage WAL pour le débit d’écriture et PgBouncer pour le pooling de connexions. Ensemble, ces techniques permettent de traiter des centaines de milliers de lignes par seconde.\u003C\u002Fp>\n","fr","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:29.353447Z","Pipeline de données haut débit — Insertions par lots, COPY et résolution de conflits","Pipelines PostgreSQL haut débit : protocole COPY, upserts en masse, réglage WAL, PgBouncer et monitoring pg_stat_statements.","postgresql pipeline haut débit",null,"index, follow",[22,27,31,35],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000012","DevOps","devops","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000022","Performance","performance",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000005","PostgreSQL","postgresql",{"id":36,"name":37,"slug":38,"created_at":26},"c0000000-0000-0000-0000-000000000001","Rust","rust",[40,47,53],{"id":41,"title":42,"slug":43,"excerpt":44,"locale":12,"category_name":45,"published_at":46},"d0000000-0000-0000-0000-000000000677","Pourquoi Bali devient le hub impact-tech d'Asie du Sud-Est en 2026","pourquoi-bali-devient-hub-impact-tech-asie-sud-est-2026","Bali se classe 16e parmi les écosystèmes startups d'Asie du Sud-Est. Avec une concentration croissante de bâtisseurs Web3, de startups IA durables et d'entreprises eco-travel tech, l'île se forge une identité de capitale impact-tech de la région.","Ingénierie","2026-03-28T10:44:49.517126Z",{"id":48,"title":49,"slug":50,"excerpt":51,"locale":12,"category_name":45,"published_at":52},"d0000000-0000-0000-0000-000000000676","Le patchwork de la protection des données ASEAN : checklist de conformité pour les développeurs","patchwork-protection-donnees-asean-checklist-conformite-developpeurs","Sept pays de l'ASEAN disposent désormais de lois complètes sur la protection des données, chacune avec des modèles de consentement, des exigences de localisation et des structures de sanctions différents. Voici une checklist pratique de conformité pour les développeurs.","2026-03-28T10:44:49.504560Z",{"id":54,"title":55,"slug":56,"excerpt":57,"locale":12,"category_name":45,"published_at":58},"d0000000-0000-0000-0000-000000000675","La transformation numérique de 29 milliards de dollars d'Indonesia : opportunités pour les éditeurs de logiciels","transformation-numerique-29-milliards-dollars-indonesia-opportunites-editeurs-logiciels","Le marché des services informatiques d'Indonesia devrait atteindre 29,03 milliards de dollars en 2026, contre 24,37 milliards en 2025. L'infrastructure cloud, l'IA, le e-commerce et les centres de données tirent la croissance la plus rapide d'Asie du Sud-Est.","2026-03-28T10:44:49.469231Z",{"id":13,"name":60,"slug":61,"bio":62,"photo_url":19,"linkedin":19,"role":63,"created_at":64,"updated_at":64},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]