6 points par GN⁺ 2026-01-21 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Présentation de trois approches créatives pour améliorer les performances des requêtes PostgreSQL en sortant des méthodes classiques, au lieu d’ajouter des index ou de réécrire les requêtes
  • Élimination des scans complets de table via des contraintes CHECK, optimisation de la faible cardinalité avec des index basés sur des fonctions, et mise en œuvre d’une contrainte d’unicité avec des index Hash
  • 1. Utiliser le paramètre constraint_exclusion pour éviter les scans inutiles dans les requêtes comportant des conditions erronées
  • 2. Utiliser des index basés sur des fonctions et des colonnes générées virtuelles (virtual generated column) pour réduire la taille des index et garantir la cohérence des requêtes
  • 3. Combiner des index Hash et des contraintes d’exclusion (exclusion constraint) pour implémenter efficacement une contrainte d’unicité sur de gros champs texte, avec d’importantes économies d’espace de stockage

Éliminer les scans complets de table avec des contraintes CHECK

  • Même si une contrainte CHECK n’autorise que les valeurs 'free' et 'pro' dans la colonne plan, si une requête erronée est exécutée avec 'Pro', PostgreSQL parcourt toute la table
    • Le plan d’exécution lit les 100�00 lignes, alors que le résultat réel est de 0 ligne
  • En définissant le paramètre constraint_exclusion sur 'on', PostgreSQL tient compte des contraintes et supprime entièrement le scan
    • Le temps d’exécution passe de 7,4 ms à 0,008 ms
  • La valeur par défaut est 'partition', et sur des requêtes simples, la surcharge de planification peut au contraire augmenter
    • En revanche, dans un environnement de BI et de reporting, où les utilisateurs saisissent souvent des conditions incorrectes, le réglage sur 'on' peut être utile

Optimiser la faible cardinalité avec des index basés sur des fonctions

  • Sur la table sale, qui contient 10 millions d’enregistrements de ventes, une requête d’agrégation du chiffre d’affaires quotidien prend 627 ms avec un scan complet
  • L’ajout d’un index B-Tree sur la colonne sold_at réduit ce temps à 187 ms, mais la taille de l’index grimpe à 214 MB
  • En créant un index basé sur une fonction sur l’expression date_trunc('day', sold_at), la taille tombe à 66 MB et le temps d’exécution s’améliore encore à 145 ms
    • La faible cardinalité permet une déduplication de l’index
  • En revanche, l’expression de la requête doit correspondre exactement à la définition de l’index, ce qui impose de maintenir la cohérence des expressions
    • Pour cela, on peut créer une VIEW contenant la même expression, ou
    • ajouter une colonne générée virtuelle (virtual generated column), prise en charge à partir de PostgreSQL 18, afin d’automatiser cette cohérence
  • Avec une colonne générée virtuelle, l’index est utilisé automatiquement, ce qui permet d’obtenir à la fois un petit index, des requêtes plus rapides et une cohérence des expressions
  • Toutefois, dans PostgreSQL 18, la création d’index sur des colonnes virtuelles n’est pas encore prise en charge, un support étant prévu dans la version 19

Implémenter une contrainte d’unicité avec des index Hash

  • Dans une table urls stockant de longues URL, la création d’un index unique basé sur B-Tree pour empêcher les doublons d’URL fait monter la taille de l’index à 154 MB
  • Un index Hash ne stocke pas les valeurs réelles mais uniquement leur hachage, ce qui le rend beaucoup plus compact
    • PostgreSQL ne prend pas en charge par défaut les index Hash uniques, mais
    • il est possible de contourner cette limite pour implémenter une contrainte d’unicité à l’aide d’une contrainte d’exclusion (exclusion constraint) sous la forme EXCLUDE USING HASH (url WITH =)
  • Avec cette méthode, une insertion en double provoque également une erreur, et les performances des requêtes sont supérieures à celles du B-Tree (0.022 ms vs 0.046 ms)
  • La taille de l’index est de 32 MB, soit plus de 5 fois plus petit qu’un B-Tree
  • Inconvénients :
    • impossible de référencer la colonne avec une clé étrangère (contrainte REFERENCES impossible)
    • compatibilité limitée avec la syntaxe INSERT ... ON CONFLICT
    • remplacement possible par ON CONFLICT ON CONSTRAINT ou la syntaxe MERGE
  • Les index Hash sont adaptés à la garantie d’unicité sur de gros champs texte et constituent une alternative efficace en espace lorsqu’aucune clé étrangère n’est nécessaire

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.