Documentation PostgreSQL 9.3.25 > Internes > Définition de l'interface des méthodes d'accès aux index | |
Lectures supplémentaires | Fonctions de la méthode d'accès aux index |
Ce chapitre définit l'interface entre le système PostgreSQL™ et les méthodes d'accès aux index, qui gérent les types d'index individuels. Le système principal ne sait rien des index en dehors de ce qui est spécifié ici. Il est donc possible de développer de nouveaux types d'index en écrivant du code supplémentaire.
Tous les index de PostgreSQL™ sont connus techniquement en tant qu'index secondaires ; c'est-à-dire que l'index est séparé physiquement du fichier de table qu'il décrit. Chaque index est stocké dans sa propre relation physique et donc décrit par une entrée dans le catalogue pg_class. Le contenu d'un index est entièrement contrôlé par la méthode d'accès à l'index. En pratique, toutes les méthodes d'accès aux index les divisent en pages de taille standard de façon à utiliser le gestionnaire de stockage et le gestionnaire de tampon pour accéder au contenu de l'index. De plus, toutes les méthodes existantes d'accès aux index utilisent la disposition de page standard décrite dans Section 58.6, « Emplacement des pages de la base de données » et le même format pour les en-têtes de ligne de l'index ; mais ces décisions ne sont pas contraintes sur une méthode d'index.
Dans les faits, un index est une correspondance entre les valeurs des clés de données et les identifiants de lignes (tuple identifiers, ou TIDs) des versions de lignes dans la table parent de l'index. Un TID consiste en un numéro de bloc et un numéro d'élément à l'intérieur de ce bloc (voir Section 58.6, « Emplacement des pages de la base de données »). C'est une information suffisante pour récupérer une version de ligne particulière à partir de la table. Les index n'ont pas directement la connaissance de l'existence éventuelle, sous MVCC, de plusieurs versions de la même ligne logique ; pour un index, chaque ligne est un objet indépendant qui a besoin de sa propre entrée dans l'index. Du coup, la mise à jour d'une ligne crée toujours toutes les nouvelles entrées d'index pour la ligne, même si les valeurs de la clé ne changent pas. (Les lignes HOT sont une exception ; mais les index ne sont pas concernés.) Les entrées d'index pour les lignes mortes sont réclamées (par le VACUUM) lorsque les lignes mortes elles-même sont réclamées.
Chaque méthode d'accès à l'index est décrite par une ligne dans le catalogue système pg_am (voir Section 47.3, « pg_am »). Le contenu principal d'une ligne de pg_am est constitué de références à des entrées de pg_proc qui identifient les fonctions d'accès à l'index fournies par la méthode d'accès. Les API de ces fonctions sont définies plus loin dans ce chapitre. De plus, la ligne de pg_am spécifie quelques propriétés fixes de la méthode d'accès, comme le support des index multi-colonnes. Il n'existe pas de support spécial pour la création ou la suppression d'entrées dans pg_am ; toute personne capable d'écrire une nouvelle méthode d'accès est supposée assez compétente pour insérer la ligne appropriée.
Pour être utile, une méthode d'accès à l'index doit aussi avoir une ou plusieurs familles d'opérateur et classes d'opérateur définies dans pg_opfamily, pg_opclass, pg_amop et pg_amproc. Ces entrées permettent au planificateur de déterminer les types de qualification des requêtes qui peuvent être utilisés avec les index de cette méthode d'accès. Les familles et classes d'opérateurs sont décrites dans Section 35.14, « Interfacer des extensions d'index », qui est un élément requis pour comprendre ce chapitre.
Un index individuel est défini par une entrée dans pg_class le définissant comme une relation physique, et une entrée dans pg_index affichant le contenu logique de l'index -- c'est-à-dire ses colonnes d'index et la sémantique de ces colonnes, telles que récupérées par les classes d'opérateur associées. Les colonnes de l'index (valeurs clés) peuvent être des colonnes simples de la table sous-jacente ou des expressions sur les lignes de la table. Habituellement, la méthode d'accès à l'index ne s'intérese pas à la provenance des valeurs clés de l'index (ce sont toujours des valeurs clés pré-traitées), mais trouve beaucoup d'intérêt aux informations de la classe d'opérateur dans pg_index. Les entrées de ces deux catalogues peuvent être accédées comme partie de la structure de données de Relation passée à toute opération sur l'index.
Certaines colonnes d'options de pg_am ont des implications peu évidentes. Les besoins de amcanunique sont discutés dans Section 54.5, « Vérification de l'unicité de l'index ». L'option amcanmulticol indique que la méthode d'accès supporte les index multi-colonnes alors que amoptionalkey indique que des parcours sont autorisés lorsqu'aucune clause de restriction indexable n'est donnée pour la première colonne de l'index. Quand amcanmulticol est faux, amoptionalkey indique essentiellement si la méthode d'accès autorise les parcours complets de l'index sans clause de restriction. Les méthodes d'accès qui supportent les colonnes d'index multiples doivent supporter les parcours qui omettent des restrictions sur une ou toutes les colonnes après la première ; néanmoins, elles peuvent imposées qu'une restriction apparaisse pour la première colonne de l'index, ce qui est signalé par l'initialisation de amoptionalkey à faux. Une raison pour laquelle une méthode d'accès d'index initialiserait amoptionalkey à false est qu'elle n'indexe pas les valeurs NULL. Comme la plupart des opérateurs indexables sont stricts et, du coup, ne peuvent pas renvoyer TRUE pour des entrées NULL, il est à première vue attractif de ne pas stocker les entrées d'index pour les valeurs NULL : un parcours d'index ne peut, de toute façon, pas les retourner. Néanmoins, cet argument tombe lorsqu'un parcours d'index n'a pas de clause de restriction pour une colonne d'index donnée. En pratique, cela signifie que les index dont amoptionalkey vaut true doivent indexer les valeurs NULL, car le planificateur peut décider d'utiliser un tel index sans aucune clé de parcours. Une restriction en découle : une méthode d'accès qui supporte des colonnes d'index multiples doit supporter l'indexage des valeurs NULL dans les colonnes qui suivent la première, car le planificateur suppose que l'index peut être utilisé pour les requêtes qui ne restreignent pas ces colonnes. Par exemple, si l'on considère un index sur (a,b) et une requête avec WHERE a = 4, le système suppose que l'index peut être utilisé pour rechercher les lignes pour lesquelles a = 4, ce qui est faux si l'index omet les lignes où b est null. Néanmoins, il est correct d'omettre les lignes où la première colonne indexée est NULL. Du coup, une méthode d'accès d'index qui ne s'occupe pas des valeurs NULL pourrait aussi configurer amsearchnulls, indiquant ainsi qu'elle supporte les clauses IS NULL et IS NOT NULL dans les conditions de recherche.