49. Définition de l'interface des méthodes d'accès aux index

49.1. Entrées du catalogue pour les index
49.2. Fonctions de la méthode d'accès aux index
49.3. Parcours d'index
49.4. Considérations pour le verrouillage d'index
49.5. Vérification de l'unicité de l'index
49.6. Fonctions d'estimation des coûts d'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.