30 points par GN⁺ 2026-01-26 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Les index PostgreSQL sont des structures essentielles pour accélérer l’accès aux données, en réduisant la quantité de données à lire sur le disque afin d’améliorer les performances des requêtes
  • Les index existent sous différentes formes, notamment Btree, Hash, BRIN, GIN, GiST, SP-GiST, chacune étant optimisée pour des caractéristiques de données et des modèles de requêtes différents
  • Les index impliquent plusieurs coûts, notamment en espace disque, performances d’écriture, complexité du query planner et utilisation mémoire
  • Des fonctionnalités avancées comme les index partiels, index multicolonnes, index de couverture et index d’expression permettent de maximiser l’efficacité dans des cas précis
  • Le choix et la gestion appropriés des index sont présentés comme un élément clé de l’optimisation des performances de PostgreSQL

Concepts de base des index

  • Un index est une structure qui permet à la base de données de réduire la quantité de données lues sur le disque afin d’accélérer les requêtes
    • Les clés primaires, clés uniques et contraintes d’exclusion sont également implémentées via des index
    • Un index est efficace lorsque le résultat de la requête représente moins de 15 à 20 % de la table entière ; au-delà, un sequential scan peut être plus efficace
  • PostgreSQL fournit par défaut 6 types d’index, et d’autres peuvent être utilisés via des extensions
    • Chaque index relie une valeur de clé à la position correspondante des données (TID)

Structure des données stockées sur disque

  • Les tables PostgreSQL sont stockées sous forme de fichiers heap, organisés en pages de 8 KB
  • Chaque ligne (tuple) est stockée sans ordre particulier, et son adresse interne est identifiée par ctid (current tuple id)
    • Exemple : (0,1) signifie le premier tuple de la page 0
  • Les index relient ces positions dans le heap (ctid) dans une structure arborescente afin de permettre une recherche rapide

Comment les index accélèrent l’accès aux données

  • Sans index, PostgreSQL effectue un sequential scan en lisant toutes les pages
    • Dans l’exemple de requête, la recherche de name='Ronaldo' lit 6272 pages et prend 265 ms
  • Avec un index, l’exécution bascule vers un Index Scan, qui ne lit que 4 pages et se termine en 0,077 ms
    • L’index associe les valeurs à leur ctid afin de retrouver rapidement uniquement les lignes nécessaires
  • La taille d’un fichier d’index peut être comparable à celle de la table (ex. : table de 30 MB → index de 30 MB)

Les coûts liés aux index

  • Au-delà du gain de performance, les index s’accompagnent de plusieurs contraintes

Espace disque

  • Les index occupent un espace de stockage séparé et peuvent être plus volumineux que la table
    • Cela engendre des coûts supplémentaires lors des sauvegardes, de la réplication et de la reprise après incident
    • L’efficacité de l’espace peut être améliorée avec des index partiels, index multicolonnes, BRIN, etc.

Opérations d’écriture

  • Lors de UPDATE, INSERT et DELETE, si une colonne indexée est modifiée, cela entraîne un surcoût de mise à jour de l’index

Query planner

  • Plus il y a d’index, plus les options à considérer par le planner augmentent, ce qui allonge le temps nécessaire à l’établissement du plan de requête

Utilisation mémoire

  • Les pages d’index sont chargées et mises en cache dans le shared buffer, ce qui augmente la pression mémoire quand les index se multiplient
  • En raison de la limite de taille des nœuds btree, plus les colonnes sont volumineuses, plus la profondeur de l’arbre augmente
  • Des opérations comme le tri, les scans multicolonnes, vacuum, reindex, etc. consomment également davantage de work memory

Principaux types d’index

Btree

  • Structure d’index par défaut de PostgreSQL, c’est l’index générique utilisé par la plupart des SGBD
    • Il permet des recherches rapides avec une complexité temporelle de O(log n)
    • Il repose sur une structure d’arbre équilibré où toutes les feuilles ont la même profondeur
    • Il est avantageux pour les opérations ORDER BY et JOIN, et sert aux contraintes de clé primaire et clé unique
  • Les nœuds internes stockent des pointeurs vers les nœuds inférieurs, tandis que les feuilles stockent les clés et les pointeurs vers le heap
  • Des pointeurs vers les nœuds gauche et droit permettent une navigation bidirectionnelle
Utilisation de plusieurs index
  • PostgreSQL peut combiner plusieurs index via des opérations bitmap AND/OR pour traiter des conditions composées
    • Exemple : pour la condition age=30 AND login_count=100, les bitmaps de deux index sont combinés
Index multicolonnes
  • Il est possible de regrouper plusieurs colonnes dans un seul index pour économiser de l’espace et améliorer la vitesse
    • Toutefois, l’ordre des colonnes est important, et seules les conditions correspondant au préfixe gauche peuvent utiliser l’index
Index partiels
  • Ils indexent uniquement certaines lignes à l’aide d’une condition
    • Réduction de la taille de l’index, meilleure adaptation à la RAM et amélioration de la vitesse de lecture
    • Exemple : create index on rules(status) where status='enabled';
    • Ils sont utiles lorsque la distribution des valeurs est déséquilibrée (status <> 'TODO', etc.)
Index de couverture
  • Si toutes les colonnes nécessaires à la requête sont incluses dans l’index, il est possible de retourner le résultat sans accès au heap (index-only scan)
    • create index abc_cov_idx on bar(a, b) including c;
    • Ils sont plus efficaces en espace que les index multicolonnes
Index d’expression
  • Ils indexent non pas la valeur brute d’une colonne, mais le résultat d’une fonction ou d’une expression
    • Exemple : CREATE INDEX idx_lower_name ON customers (lower(name));
    • Ils sont utiles pour les recherches sur des valeurs transformées comme LOWER(name)
    • Seules les fonctions immutables peuvent être utilisées

Hash

  • Index basé sur une structure de table de hachage, efficace en espace pour les longues chaînes ou les UUID
    • Il stocke un code de hachage sur 32 bits afin de réduire la taille
    • Il ne prend en charge que les comparaisons d’égalité (=), et ne permet ni tri ni index multicolonnes
    • Lorsque la distribution de hachage est uniforme, il peut offrir des performances de lecture supérieures à Btree
  • Selon la documentation officielle, les index hash réduisent les E/S sur les grandes tables grâce à un accès direct aux pages de bucket

BRIN (Block Range Index)

  • Index qui ne stocke que les valeurs minimales et maximales de chaque plage de blocs
    • Il est extrêmement compact et favorable au cache
    • Il convient aux très grandes tables, aux données append-only et aux séries temporelles
  • Si les lignes sont souvent mises à jour, son efficacité diminue à cause des duplications liées au MVCC
  • Le paramètre pages_per_range permet d’ajuster le compromis entre précision et taille

GIN (Generalized Inverted Index)

  • Index adapté à la recherche dans des données composées
    • Il prend en charge la recherche d’éléments spécifiques dans du texte, des tableaux, du JSONB, etc.
    • Il utilise des stratégies dédiées (opclass) selon le type de données
    • Pour JSON, il est recommandé d’utiliser des colonnes JSONB ; pour le texte, tsvector ou l’extension pg_trgm

GiST & SP-GiST

  • Le Generalized Search Tree (GiST) et le Space-Partitioned GiST (SP-GiST) sont des frameworks d’implémentation d’index pour certains types de données
    • GiST prend en charge une structure équilibrée, tandis que SP-GiST prend en charge une structure déséquilibrée
    • Ils sont utilisés pour les données géographiques, inet, intervalles, vecteurs de texte, etc.
    • GIN offre des lectures plus rapides, tandis que GiST coûte moins cher à construire et à maintenir
    • Pour la recherche plein texte, le choix entre les deux dépend des besoins

Conclusion

  • Les index sont au cœur de l’optimisation des performances de PostgreSQL, et il est essentiel de trouver un équilibre entre vitesse de lecture et coûts d’écriture et de stockage
  • En choisissant le type d’index adapté aux caractéristiques des données et aux modèles de requêtes, il est possible d’exploiter une base de données plus rapide et plus efficace
  • Une conception appropriée des index est un élément indispensable pour garantir la scalabilité et la stabilité des systèmes à grande échelle

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.