49. Définition de l'interface des méthodes 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ére les types
d'index individuels. Le système principal ne sait rien des index en
dehors de ce qui est spécifié ici, donc il est possible de développer
de nouveaux types d'index en écrivant un 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
de la table qu'il décrit. Chaque index est stocké dans sa propre
relation physique et est donc décrit par
une entrée dans le catalogue pg_class. Le contenu d'un index est entièrement
sous le contrôle de la méthode d'accès à l'index. En pratique, toutes
les méthodes d'accès aux index se divisent en pages de taille
standard pour qu'elles puissent 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 la page standard décrite dans Section 52.3,
« Emplacement des pages de la base de données », et
elles utilisent toutes 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).
En fait, un index est une correspondance de valeurs clés de données
en 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 52.3,
« 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 ne sont pas directement
conscients que, sous MVCC, il pourrait y avoir 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,
une 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 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.
49.1. Entrées du catalogue pour les index
Chaque méthode d'accès à l'index est décrite par une ligne dans le
catalogue système pg_am (voir
Section 43.3, « pg_am »). Le contenu principal d'une
ligne de pg_am est constitué de
références à des entrées de
pg_proc
identifiant les fonctions d'accès à
l'index fournis par la méthode d'accès. Les API pour ces fonctions
sont définies plus tard 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 à plusieurs
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 une ligne appropriée
elle-même.
Pour être utile, une méthode d'accès à l'index doit aussi avoir une
ou plusieurs classes d'opérateur
définies dans
pg_opclass
,
pg_amop
et
pg_amproc
. Ces entrées autorisent le
planificateur à déterminer le type de qualification des requêtes
pouvant être utilisé avec les index de cette méthode d'accès. Les
classes d'opérateurs sont décrites dans Section 33.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 des
colonnes d'index qu'il a et de la sémantique de ces colonnes, de la
façon dont elles sont récupérées par les classes d'opérateur
associées. Les colonnes de l'index (valeurs clés) peuvent être soit
des colonnes simples de la table sous-jacente soit des expressions
sur les lignes de la table. Habituellement, la méthode d'accès à
l'index n'a aucun intérêt dans l'emplacement d'où provient les
valeurs clés de l'index (ce sont toujours des valeurs clés
pré-traitées) mais il sera très intéressé dans les informations de
la classe d'opérateur dans pg_index. Ces entrées de catalogue peuvent être
accédées car elles font partie de la structure de données de
Relation qui est passée dans toutes
les opérations de l'index.
Certaines des colonnes d'options de pg_am ont des obligations peu évidentes. Les
besoins de
amcanunique
sont
discutés dans Section 49.5,
« Vérification de l'unicité de l'index ». L'option
amcanmulticol
assure que la
méthode d'accès supporte les index multicolonnes alors que
amoptionalkey
assure qu'il
fera des parcours où aucune clause indexable de restriction 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
plusieurs colonnes d'index
doivent
supporter les parcours omettant
les restrictions d'une ou de toutes les colonnes suivant la
première ; néanmoins, elles sont autorisées à réclamer quelque
restrictions pour apparaître dès la première colonne de l'index, et
ceci est signalé en initialisant
amoptionalkey
à faux.
amindexnulls
assure que les index de
l'entrée sont créés pour les valeurs clés 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 attratif
de ne pas stocker les entrées d'index pour les valeurs NULL : de
toute façon, elles ne peuvent pas être renvoyées par un parcours
d'index. Néanmoins, cet argument échoue quand 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 pourrait décider d'utiliser
un tel index sans clés parcourus. Une restriction relative est
qu'une méthode d'accès à l'index qui supporte plusieurs colonnes
d'index
doit
supporter
l'indexage des valeurs NULL dans les colonnes suivant la première
car le planificateur supposera que l'index peut être utilisé pour
les requêtes qui ne restreignent pas ces colonnes. Par exemple,
considérez un index sur (a,b) et une requête avec WHERE a = 4. Le système supposera que l'index peut
être utilisé pour les lignes avec a = 4,
ce qui est mauvais 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,
amindexnulls
doit valoir true seulement
si la méthode d'accès à l'index indexe toutes les lignes, ceci
incluant les combinaisons arbitraires des valeurs NULL.