PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Indizierung ando:GIN-Indizes

PostgreSQL hat mehrere Arten von Indizes:B-Tree, Hash, GiST, Gin und SP-GiST. Offensichtlich deckt jeder von ihnen einen bestimmten Bedarf ab. Zum Beispiel sagt die PostgreSQL-Dokumentation über GIN-Indizes:

GIN-Indizes können also verwendet werden, um die Elemente eines Arrays, eines hstore usw. zu indizieren.

Aber dieses Mal werden wir über eines dieser Contrib-Module sprechen, die mehr Arten von Operatoren bereitstellen, die mit GIN-Indizes verwendet werden können:pg_trgm.

Dieses Modul erstellt Trigramme aus Textzeichenfolgen, sodass es verwendet werden kann, um Ähnlichkeiten zu finden. Dadurch können GIN-ähnliche Indizes, die die Operatorklasse gin_trgm_ops verwenden, in LIKE-Suchen verwendet werden, selbst wenn der Platzhalter „%“ am Anfang des Suchmusters gefunden wird (z. B.:LIKE-Name „%jaime%“).

Um einen so verwendbaren Index zu erstellen, muss der Index folgendermaßen erstellt werden:

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

Mit einem Index wie diesem habe ich gesehen, wie Abfragen von über 10 Sekunden auf wenige Millisekunden gesunken sind; Bevor Sie sich jedoch mit der Erstellung dieser Indizes beeilen, lassen Sie uns die Probleme betrachten, die Sie haben.

Betrachten Sie die folgende Abfrage "select show_trgm('Jaime Casanova');" Dies zeigt uns die Trigramme einer Textzeichenfolge, in diesem Fall 15 Trigramme. Es ist also nicht schwer vorstellbar, dass diese Art von Index stark wächst, und je größer die Textzeichenfolgen sind, desto mehr wächst der Index (weil es mehr Trigramme geben wird). Eine weitere offensichtliche Schlussfolgerung ist, dass die Pflege dieser Art von Indizes teuer sein kann, tatsächlich können sie die Leistung von INSERT und UPDATE stark beeinträchtigen, insbesondere wenn es mehrere dieser Indizes in derselben Tabelle gibt, um dieses Problem ein wenig zu reduzieren, eine Technik namens fastupdate erfunden, die darin besteht, eine ungeordnete Liste von anhängigen zu führen. Also fügen INSERT und UPDATE nicht in den Hauptindex ein, sondern in diese zusätzliche Struktur, bis ein VACUUM auftritt oder bis die Pending-Liste größer als work_mem wird. Die Nachteile sind:1) Beim Lesen des Indexes muss auch diese zusätzliche Struktur gelesen werden, was die Abfrageleistung beeinträchtigen kann; und 2) ein INSERT oder UPDATE kann dazu führen, dass der Rückstand zu groß wird und daher mit der Verarbeitung des Rückstands beginnt, was sich auf dieses INSERT oder UPDATE und alle anderen Operationen auswirkt, die gleichzeitig auf dieser Tabelle ausgeführt werden.

Abschließend; Ein GIN-Index zusammen mit dem pg_trgm-Modul kann die Leistung einiger Abfragen erheblich verbessern, sie sollten jedoch nicht missbraucht werden, da sie ein zweischneidiges Schwert sein können.