blog/database-optimization
Performance20 mars 2026·13 min

Optimisation des bases de données : indexation, partitionnement et réplication

Techniques avancées pour des requêtes SQL en millisecondes sur des tables de millions de lignes.

PostgreSQLIndexationShardingRéplication

La base de données est souvent le bottleneck

Dans la plupart des applications, la base de données est le goulot d'étranglement principal. Une requête mal optimisée peut prendre 10 secondes au lieu de 10 millisecondes — un facteur 1000x. Les trois leviers principaux sont l'indexation, le partitionnement et la réplication.

Indexation : l'arme n°1

Un index est une structure de données (B-tree, Hash, GIN, GiST) qui permet à la base de trouver des lignes sans scanner toute la table. Sans index, une recherche sur 10M de lignes nécessite un full table scan. Avec un index B-tree, c'est un parcours logarithmique — O(log n) au lieu de O(n).

  • Index B-tree : le plus courant, optimal pour =, <, >, BETWEEN, ORDER BY
  • Index Hash : uniquement pour l'égalité exacte (=), plus rapide que B-tree pour ce cas
  • Index GIN : pour les recherches full-text, JSONB et arrays (PostgreSQL)
  • Index partiel : indexe uniquement un sous-ensemble de lignes (WHERE status = 'active')
  • Index composite : plusieurs colonnes, l'ordre des colonnes est crucial (règle du leftmost prefix)

EXPLAIN ANALYZE : lire un plan d'exécution

EXPLAIN ANALYZE est votre meilleur ami pour l'optimisation. Il montre exactement comment PostgreSQL exécute une requête : quels index sont utilisés, combien de lignes sont scannées, et où se trouve le bottleneck.

sql
-- Avant optimisation : Seq Scan (5.2 secondes)
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 42;
-- Seq Scan on orders (cost=0.00..185432.00 rows=100 width=64)
--   Filter: (user_id = 42)
--   Rows Removed by Filter: 9999900
--   Execution Time: 5234.567 ms

-- Après CREATE INDEX idx_orders_user_id ON orders(user_id);
-- Index Scan using idx_orders_user_id (cost=0.43..12.45 rows=100 width=64)
--   Index Cond: (user_id = 42)
--   Execution Time: 0.234 ms   ← 22000x plus rapide

Partitionnement et Sharding

Quand une table dépasse les dizaines de millions de lignes, même les index ne suffisent plus. Le partitionnement divise logiquement une table en sous-tables, le sharding distribue physiquement les données sur plusieurs serveurs.

  • Partitionnement par range : par date (logs mensuels), par ID (0-1M, 1M-2M)
  • Partitionnement par hash : distribution uniforme, bon pour l'écriture parallèle
  • Partitionnement par liste : par région, par catégorie
  • Sharding : chaque shard est une base indépendante, complexité de routing et de joins cross-shard

Réplication : lecture scalable

La réplication crée des copies de la base pour distribuer la charge de lecture. Le pattern classique est un primary (écritures) avec N replicas (lectures). PostgreSQL supporte la réplication streaming synchrone et asynchrone.

  • Réplication asynchrone : latence minimale en écriture, risque de lecture stale (read-after-write inconsistency)
  • Réplication synchrone : cohérence forte mais latence d'écriture accrue (attente de l'ACK du replica)
  • Read replicas : router les SELECT vers les replicas, les INSERT/UPDATE vers le primary
  • Connection pooling (PgBouncer) : réduire le coût des connexions, indispensable à >100 connexions
Adama Niasse

Adama Niasse

Software Engineer · Cloud-DevOps · Cybersecurity

À propos
/
Adama.

Software Engineer basé au Sénégal. Spécialisé en Go, Rust, Cloud-DevOps et Cybersécurité. Passionné par les systèmes distribués et les architectures performantes.

Stack

  • Nuxt 3
  • Tailwind CSS
  • Vercel

Status

Disponible

Ouvert aux missions freelance et collaborations.

Me contacter

© 2026 Adama Niasse. Tous droits réservés.

Dakar, Sénégal