PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Indexation ando :Index GIN

PostgreSQL possède plusieurs types d'index :B-tree, Hash, GiST, Gin et SP-GiST. Évidemment chacun d'eux couvre un besoin spécifique. Par exemple, la documentation de PostgreSQL dit à propos des index GIN :

Ainsi, les index GIN peuvent être utilisés pour indexer les éléments d'un tableau, d'un hstore, etc.

Mais cette fois, nous allons parler d'un de ces modules contrib qui fournissent plus de types d'opérateurs pouvant être utilisés avec les index GIN :​​pg_trgm.

Ce module crée des trigrammes de chaînes de texte afin qu'il puisse être utilisé pour trouver des similitudes. Cela permet aux index de type GIN qui utilisent la classe d'opérateurs gin_trgm_ops d'être utilisés dans les recherches LIKE même lorsque le caractère générique '%' est trouvé au début du modèle de recherche (par exemple :nom LIKE '%jaime%').

Pour créer un index qui peut être utilisé comme ceci, l'index doit être créé comme ceci :

CREATE INDEX idx_gin ON table USING GIN (campo_texto gin_trgm_ops);

Avec un index comme celui-ci, j'ai vu des requêtes chuter de plus de 10 secondes à quelques millisecondes; cependant, avant de vous précipiter pour créer ces index, considérons les problèmes que vous rencontrez.

Considérez la requête suivante "select show_trgm('Jaime Casanova');" Cela nous montre les trigrammes d'une chaîne de texte, dans ce cas 15 trigrammes. Il n'est donc pas difficile d'imaginer que ce type d'index grandit beaucoup, et plus les chaînes de texte sont grandes, plus l'index grandit (car il y aura plus de trigrammes). Une autre conclusion évidente est que le maintien de ce type d'index peut être coûteux, en fait ils peuvent grandement affecter les performances de INSERT et UPDATE, surtout s'il y a plusieurs de ces index sur la même table, pour réduire un peu ce problème une technique appelée fastupdate a été inventé qui consiste à maintenir une liste non ordonnée d'attentes. Ainsi, INSERT et UPDATE au lieu de s'insérer dans l'index principal, ils le font dans cette structure supplémentaire jusqu'à ce qu'un VACUUM se produise ou jusqu'à ce que la liste en attente devienne plus grande que work_mem. Les inconvénients sont :1) la lecture de l'index doit également lire cette structure supplémentaire, ce qui peut affecter les performances des requêtes; et 2) un INSERT ou UPDATE peut entraîner une croissance trop importante du backlog et commencera donc à traiter le backlog, ce qui affectera cet INSERT ou UPDATE et toutes les autres opérations se déroulant simultanément sur cette table.

En conclusion; un index GIN associé au module pg_trgm peut grandement améliorer les performances de certaines requêtes, mais il ne faut pas en abuser car il peut s'agir d'une épée à double tranchant.