Il existe deux types d'index qui peuvent être utilisés pour accélérer les recherches plein texte : GIN et GiST. Notez que les index ne sont pas obligatoires pour la recherche plein texte, mais, dans les cas où une colonne est utilisée fréquemment dans une recherche, un index sera suffisamment intéressant.
Pour créer un tel index, faites l'un des deux :
CREATE INDEX nom
ON table
USING GIN(colonne
);
Crée un index GIN (Generalized Inverted Index).
La colonne
doit être de type
tsvector
.
CREATE INDEX nom
ON table
USING GIST (colonne
[ { DEFAULT | tsvector_ops } (siglen = nombre
) ] );
Crée un index GiST (Generalized Search Tree).
La colonne
peut être de type
tsvector
ou tsquery
. Le paramètre entier
optionnel siglen
détermine la longueur de la
signature en octets (voir ci-dessous pour les détails).
Les index GIN sont le type d'index préféré pour la recherche plein texte.
En tant qu'index inversés, ils contiennent une entrée d'index pour chaque
mot (lexème), avec une liste compressée des emplacements correspondants.
Les recherches multimots peuvent trouver la première correspondance, puis
utiliser l'index pour supprimer les lignes qui ne disposent pas des autres
mots recherchés. Les index GIN stockent uniquement les mots (lexèmes) des
valeurs de type tsvector
, et non pas les labels de poids. De
ce fait, une vérification de la ligne de table est nécessaire quand une
recherche implique les poids.
Un index GiST est à perte, signifiant que l'index
peut produire des faux positifs, et il est nécessaire de vérifier la ligne
de la table pour les éliminer. PostgreSQL le
fait automatiquement si nécessaire. Les index GiST sont à perte, car chaque
document est représenté dans l'index par une signature à longueur fixe. La
longueur de la signature en octets est déterminée par la valeur du
paramètre optionnel de type entier nommé siglen
. La
longueur par défaut de la signature (quand siglen
n'est
pas indiqué) est 124 octets, la longueur maximale est de 2024 octets. La
signature est générée par le hachage de chaque mot en un bit aléatoire dans
une chaîne à n bits, tous ces bits étant assemblés dans une opération OR
qui produit une signature du document sur n bits. Quand deux hachages de
mots sont identiques, nous avons un faux positif. Si tous les mots de la
requête ont une correspondance (vraie ou fausse), alors la ligne de la
table doit être récupérée pour voir si la correspondance est correcte. Des
signatures plus longues amènent à une recherche plus précise (en parcourant
une fraction plus réduite de l'index et un plus petit nombre de blocs dans
la table), au prix d'un index plus gros.
Un index GiST peut être couvrant, c'est-à-dire utiliser la clause
INCLUDE
. Les colonnes incluses peuvent avoir des
types de données sans aucune classe d'opérateur GiST.
Les attributs inclus seront stockés sans compression.
La perte implique une dégradation des performances à cause de récupérations inutiles d'enregistrements de la table qui s'avèrent être de fausses correspondances. Comme les accès aléatoires aux enregistrements de la table sont lents, ceci limite l'utilité des index GiST. La probabilité de faux positifs dépend de plusieurs facteurs, en particulier le nombre de mots uniques, donc l'utilisation de dictionnaires qui réduisent ce nombre est recommandée.
Notez que le temps de construction de l'index GIN peut souvent être amélioré en augmentant maintenance_work_mem alors qu'un index GiST n'est pas sensible à ce paramètre.
Le partitionnement de gros ensembles et l'utilisation intelligente des index GIN et GiST autorise l'implémentation de recherches très rapides avec une mise à jour en ligne. Le partitionnement peut se faire au niveau de la base en utilisant l'héritage, ou en distribuant les documents sur des serveurs et en récupérant les résultats de la recherche, par exemple via un accès Foreign Data. Ce dernier est possible, car les fonctions de score utilisent les informations locales.