[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-25-partitionnement-tables-postgresql":3},{"article":4,"author":55},{"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":35},"d6000000-0000-0000-0000-000000000125","a0000000-0000-0000-0000-000000000065","Deep EVM #25 : Partitionnement de tables PostgreSQL — Quand votre table dépasse 10M+ lignes","deep-evm-25-partitionnement-tables-postgresql","Guide pratique du partitionnement de tables PostgreSQL pour les grandes tables. Couvre le partitionnement par plage, liste et hash avec exemples réels, stratégies de migration et planification de requêtes.","## Quand partitionner\n\nVous avez une table de transactions qui a commencé petite et atteint maintenant 34 millions de lignes. Les requêtes qui prenaient 50 ms prennent maintenant 5 secondes. VACUUM tourne pendant des heures. Le partitionnement de tables divise une table logique en plusieurs tables physiques, et le planificateur de requêtes de PostgreSQL route automatiquement les requêtes vers les bonnes partitions.\n\n## Types de partitionnement\n\n### Partitionnement par plage (Range)\n\nIdéal pour les données temporelles :\n\n```sql\nCREATE TABLE transactions (\n    id BIGINT GENERATED ALWAYS AS IDENTITY,\n    created_at TIMESTAMPTZ NOT NULL,\n    amount NUMERIC(18,2),\n    account_id BIGINT\n) PARTITION BY RANGE (created_at);\n\nCREATE TABLE transactions_2024_01\n    PARTITION OF transactions\n    FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');\n\nCREATE TABLE transactions_2024_02\n    PARTITION OF transactions\n    FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');\n```\n\n### Partitionnement par liste (List)\n\nIdéal pour les données catégorielles :\n\n```sql\nCREATE TABLE events (\n    id BIGINT,\n    event_type TEXT NOT NULL,\n    data JSONB\n) PARTITION BY LIST (event_type);\n\nCREATE TABLE events_transfer\n    PARTITION OF events\n    FOR VALUES IN ('transfer', 'approval');\n\nCREATE TABLE events_swap\n    PARTITION OF events\n    FOR VALUES IN ('swap', 'flash_loan');\n```\n\n### Partitionnement par hash\n\nIdéal pour la distribution uniforme :\n\n```sql\nCREATE TABLE accounts (\n    id BIGINT,\n    address TEXT NOT NULL,\n    balance NUMERIC\n) PARTITION BY HASH (id);\n\nCREATE TABLE accounts_0\n    PARTITION OF accounts\n    FOR VALUES WITH (MODULUS 4, REMAINDER 0);\n-- ... et 3 autres partitions\n```\n\n## Migration d'une table existante\n\nMigrer 34 millions de lignes vers une table partitionnée :\n\n```sql\n-- 1. Créer la nouvelle table partitionnée\nCREATE TABLE transactions_new (\n    LIKE transactions INCLUDING ALL\n) PARTITION BY RANGE (created_at);\n\n-- 2. Créer les partitions\n-- (une par mois pour les 3 dernières années)\n\n-- 3. Copier les données par lots\nINSERT INTO transactions_new\nSELECT * FROM transactions\nWHERE created_at >= '2024-01-01' AND created_at \u003C '2024-02-01';\n-- Répéter pour chaque mois\n\n-- 4. Échange atomique\nBEGIN;\nALTER TABLE transactions RENAME TO transactions_old;\nALTER TABLE transactions_new RENAME TO transactions;\nCOMMIT;\n\n-- 5. Supprimer l'ancienne table après vérification\nDROP TABLE transactions_old;\n```\n\n## Élagage de partitions\n\nLe planificateur de requêtes exclut automatiquement les partitions non pertinentes :\n\n```sql\nEXPLAIN SELECT * FROM transactions\nWHERE created_at >= '2024-06-01' AND created_at \u003C '2024-07-01';\n\n-- Scan uniquement sur transactions_2024_06\n-- Les 35 autres partitions sont ignorées\n```\n\n## Index sur les tables partitionnées\n\nChaque partition a ses propres index :\n\n```sql\n-- Index global (créé sur la table parent, répliqué sur chaque partition)\nCREATE INDEX idx_transactions_account\n    ON transactions (account_id);\n\n-- Index plus petit par partition = maintenance plus rapide\n```\n\n## VACUUM et maintenance\n\nLe principal avantage du partitionnement pour la maintenance : VACUUM peut traiter chaque partition indépendamment. Au lieu de verrouiller 34M lignes, il traite des partitions de 1-2M lignes.\n\n## Résultats\n\n| Métrique | Avant | Après | Amélioration |\n|----------|-------|-------|-------------|\n| Requête par plage de dates | 5.2s | 45ms | 115x |\n| VACUUM | 4h | 12min | 20x |\n| INSERT (débit) | 8K\u002Fs | 25K\u002Fs | 3x |\n| Taille des index | 12 GB | 400 MB\u002Fpartition | Fragmenté |\n\n## Conclusion\n\nLe partitionnement de tables PostgreSQL est essentiel quand vos tables dépassent les dizaines de millions de lignes. Le partitionnement par plage pour les données temporelles, par liste pour les catégories et par hash pour la distribution uniforme couvrent la majorité des cas d'usage.","\u003Ch2 id=\"quand-partitionner\">Quand partitionner\u003C\u002Fh2>\n\u003Cp>Vous avez une table de transactions qui a commencé petite et atteint maintenant 34 millions de lignes. Les requêtes qui prenaient 50 ms prennent maintenant 5 secondes. VACUUM tourne pendant des heures. Le partitionnement de tables divise une table logique en plusieurs tables physiques, et le planificateur de requêtes de PostgreSQL route automatiquement les requêtes vers les bonnes partitions.\u003C\u002Fp>\n\u003Ch2 id=\"types-de-partitionnement\">Types de partitionnement\u003C\u002Fh2>\n\u003Ch3>Partitionnement par plage (Range)\u003C\u002Fh3>\n\u003Cp>Idéal pour les données temporelles :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">CREATE TABLE transactions (\n    id BIGINT GENERATED ALWAYS AS IDENTITY,\n    created_at TIMESTAMPTZ NOT NULL,\n    amount NUMERIC(18,2),\n    account_id BIGINT\n) PARTITION BY RANGE (created_at);\n\nCREATE TABLE transactions_2024_01\n    PARTITION OF transactions\n    FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');\n\nCREATE TABLE transactions_2024_02\n    PARTITION OF transactions\n    FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Partitionnement par liste (List)\u003C\u002Fh3>\n\u003Cp>Idéal pour les données catégorielles :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">CREATE TABLE events (\n    id BIGINT,\n    event_type TEXT NOT NULL,\n    data JSONB\n) PARTITION BY LIST (event_type);\n\nCREATE TABLE events_transfer\n    PARTITION OF events\n    FOR VALUES IN ('transfer', 'approval');\n\nCREATE TABLE events_swap\n    PARTITION OF events\n    FOR VALUES IN ('swap', 'flash_loan');\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Partitionnement par hash\u003C\u002Fh3>\n\u003Cp>Idéal pour la distribution uniforme :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">CREATE TABLE accounts (\n    id BIGINT,\n    address TEXT NOT NULL,\n    balance NUMERIC\n) PARTITION BY HASH (id);\n\nCREATE TABLE accounts_0\n    PARTITION OF accounts\n    FOR VALUES WITH (MODULUS 4, REMAINDER 0);\n-- ... et 3 autres partitions\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"migration-d-une-table-existante\">Migration d’une table existante\u003C\u002Fh2>\n\u003Cp>Migrer 34 millions de lignes vers une table partitionnée :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">-- 1. Créer la nouvelle table partitionnée\nCREATE TABLE transactions_new (\n    LIKE transactions INCLUDING ALL\n) PARTITION BY RANGE (created_at);\n\n-- 2. Créer les partitions\n-- (une par mois pour les 3 dernières années)\n\n-- 3. Copier les données par lots\nINSERT INTO transactions_new\nSELECT * FROM transactions\nWHERE created_at &gt;= '2024-01-01' AND created_at &lt; '2024-02-01';\n-- Répéter pour chaque mois\n\n-- 4. Échange atomique\nBEGIN;\nALTER TABLE transactions RENAME TO transactions_old;\nALTER TABLE transactions_new RENAME TO transactions;\nCOMMIT;\n\n-- 5. Supprimer l'ancienne table après vérification\nDROP TABLE transactions_old;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"lagage-de-partitions\">Élagage de partitions\u003C\u002Fh2>\n\u003Cp>Le planificateur de requêtes exclut automatiquement les partitions non pertinentes :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">EXPLAIN SELECT * FROM transactions\nWHERE created_at &gt;= '2024-06-01' AND created_at &lt; '2024-07-01';\n\n-- Scan uniquement sur transactions_2024_06\n-- Les 35 autres partitions sont ignorées\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"index-sur-les-tables-partitionn-es\">Index sur les tables partitionnées\u003C\u002Fh2>\n\u003Cp>Chaque partition a ses propres index :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">-- Index global (créé sur la table parent, répliqué sur chaque partition)\nCREATE INDEX idx_transactions_account\n    ON transactions (account_id);\n\n-- Index plus petit par partition = maintenance plus rapide\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"vacuum-et-maintenance\">VACUUM et maintenance\u003C\u002Fh2>\n\u003Cp>Le principal avantage du partitionnement pour la maintenance : VACUUM peut traiter chaque partition indépendamment. Au lieu de verrouiller 34M lignes, il traite des partitions de 1-2M lignes.\u003C\u002Fp>\n\u003Ch2 id=\"r-sultats\">Résultats\u003C\u002Fh2>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Métrique\u003C\u002Fth>\u003Cth>Avant\u003C\u002Fth>\u003Cth>Après\u003C\u002Fth>\u003Cth>Amélioration\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>Requête par plage de dates\u003C\u002Ftd>\u003Ctd>5.2s\u003C\u002Ftd>\u003Ctd>45ms\u003C\u002Ftd>\u003Ctd>115x\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>VACUUM\u003C\u002Ftd>\u003Ctd>4h\u003C\u002Ftd>\u003Ctd>12min\u003C\u002Ftd>\u003Ctd>20x\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>INSERT (débit)\u003C\u002Ftd>\u003Ctd>8K\u002Fs\u003C\u002Ftd>\u003Ctd>25K\u002Fs\u003C\u002Ftd>\u003Ctd>3x\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Taille des index\u003C\u002Ftd>\u003Ctd>12 GB\u003C\u002Ftd>\u003Ctd>400 MB\u002Fpartition\u003C\u002Ftd>\u003Ctd>Fragmenté\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch2 id=\"conclusion\">Conclusion\u003C\u002Fh2>\n\u003Cp>Le partitionnement de tables PostgreSQL est essentiel quand vos tables dépassent les dizaines de millions de lignes. Le partitionnement par plage pour les données temporelles, par liste pour les catégories et par hash pour la distribution uniforme couvrent la majorité des cas d’usage.\u003C\u002Fp>\n","fr","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:29.337755Z","Partitionnement de tables PostgreSQL — Quand votre table dépasse 10M+ lignes","Guide pratique du partitionnement PostgreSQL : plage, liste et hash. Migration de 34M lignes vers 20 partitions.","partitionnement tables postgresql",null,"index, follow",[22,27,31],{"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",[36,43,49],{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":41,"published_at":42},"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":44,"title":45,"slug":46,"excerpt":47,"locale":12,"category_name":41,"published_at":48},"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":50,"title":51,"slug":52,"excerpt":53,"locale":12,"category_name":41,"published_at":54},"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":56,"slug":57,"bio":58,"photo_url":19,"linkedin":19,"role":59,"created_at":60,"updated_at":60},"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"]