PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 11.22 » Internes » Index BRIN » Introduction

67.1. Introduction

BRIN signifie Block Range Index, soit index par intervalles de bloc. BRIN est concu pour gérer de grosses tables dont certaines ont des colonnes ayant une corrélation naturelle avec leur stockage physique. Un intervalle de bloc est un groupe de pages physiquement adjacentes dans la table ; Pour chaque gamme de bloc, un résumé des informations est stocké par l'index. Un exemple courant est une table avec une colonne date, contenant les références des ventes d'un magasin. Chaque commande y serait enregistrée chronologiquement. Dans la plupart des cas, les données seront donc insérées dans le même ordre où elles apparaîtront par la suite. De la même manière, une table, avec une colonne code postal, pourrait avoir tous les codes d'une même ville rassemblés naturellement au même endroit.

Les index BRIN peuvent répondre à des requêtes via un parcours d'index bitmap classique, et retourneront toutes les lignes de toutes les pages dans chaque intervalle si le résumé des informations contenues dans l'index est cohérent avec les conditions de la requête. L'exécuteur de la requête doit revérifier ces lignes et annuler celles qui ne répondent pas aux conditions initiales de la requête. En d'autres termes, on parle d'index à perte (lossy). Comme l'index BRIN est un petit index, parcourir cet index ajoute une légère surcharge par rapport à un parcours séquentiel mais permet d'éviter de parcourir des grandes parties de la table où on sait qu'on ne trouvera pas de lignes à remonter.

Les données spécifiques qu'un index BRIN va stocker, de même que les requêtes spécifiques auquel l'index va pouvoir répondre dépendent de la classe d'opérateur choisie pour chaque colonne de l'index. Les types de données possédant un ordre de tri linéaire peuvent utiliser une classe d'opérateur qui ne conserve que la valeur minimale et la valeur maximale dans chaque intervalle de bloc. Par exemple, un type géométrique peut stocker une bounding box pour tous les objets de l'intervalle de bloc.

La taille de l'intervalle de bloc est déterminée à la création de l'index par le paramètre pages_per_range Le nombre des entrées de l'index sera égal à la taille de la relation en page, divisée par la valeur sélectionnée dans pages_per_range. De ce fait, plus ce nombre est bas, plus l'index sera volumineux (il y a plus d'entrées d'index à stocker) mais, en même temps, le résumé des informations stockées pourra être plus précis, et un nombre plus important de blocs de données pourront être ignorés pendant le parcours d'index.

67.1.1. Maintenance de l'index

Lors de la création de l'index, toutes les pages de la table sont parcourues et un résumé des lignes de l'index est créé pour chaque intervalle, incluant certainement aussi un intervalle incomplet à la fin. Lors de l'ajout de nouvelles données dans des pages déja incluses dans des résumés, cela va entrainer la mise à jour du résumé, avec les informations sur les nouvelles lignes insérées. Lorsqu'une nouvelle page est créée et qu'elle ne correspond à aucun des derniers intervalles résumés, l'intervalle ne crée pas automatiquement un résumé. Ces lignes restent non catégorisées jusqu'à ce qu'un processus soit lancé pour le faire, créant alors les résumés initiaux. Ce processus peut être appelé manuellement en exécutant la fonction brin_summarize_range(regclass, bigint) ou la fonction brin_summarize_new_values(regclass) ; automatiquement lorsque VACUUM va inspecter la table ; ou par un résumé automatique effectué par autovacuum, au fur et à mesure que des insertions sont effectuées. (Ce dernier déclencheur est désactivé par défaut, et peut être activé avec le paramètre autosummarize.) Inversement, le résumé d'un intervalle peut être supprimé en utilisant la fonction brin_desummarize_range(regclass, bigint), ce qui peut être utile quand la ligne de l'index n'est plue une bonne représentation du fait des changements des valeurs existantes.

Quand le résumé automatique est activé, chaque fois qu'un intervalle de page est rempli, une requête est envoyée à autovacuum pour qu'il exécute un résumé ciblé pour cet intervalle, opération à exécuter à la fin du travail du prochain worker sur la même base de données. Si la queue des demandes est remplie, la demande n'est pas enregistré et un message est enregistré dans les traces du serveur :

LOG:  request for BRIN range summarization for index "brin_wi_idx" page 128 was not recorded
    

Quand cela arrive, l'intervalle sera résumé avec la méthode habituelle lors du prochain VACUUM standard de la table.