PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Indicizzazione ando:Indici GIN

PostgreSQL ha diversi tipi di indici:B-tree, Hash, GiST, Gin e SP-GiST. Ovviamente ognuno di essi copre un'esigenza specifica. Ad esempio, la documentazione di PostgreSQL dice sugli indici GIN:

Quindi gli indici GIN possono essere utilizzati per indicizzare gli elementi di un array, un hstore e così via.

Ma questa volta parleremo di uno di quei moduli contrib che forniscono più tipi di operatori che possono essere utilizzati con gli indici GIN:pg_trgm.

Questo modulo crea trigrammi di stringhe di testo in modo che possa essere utilizzato per trovare somiglianze. Ciò consente agli indici simili a GIN che utilizzano la classe dell'operatore gin_trgm_ops di essere utilizzati nelle ricerche LIKE anche quando viene trovato il carattere jolly '%' all'inizio del modello di ricerca (ad esempio:nome LIKE '%jaime%').

Per creare un indice che può essere utilizzato in questo modo, l'indice deve essere creato in questo modo:

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

Con un indice come questo ho visto le query passare da oltre 10 secondi a pochi millisecondi; tuttavia, prima di affrettarti a creare questi indici, consideriamo i problemi che hai.

Considera la seguente query "select show_trgm('Jaime Casanova');" Questo ci mostra i trigrammi di una stringa di testo, in questo caso 15 trigrammi. Quindi non è difficile immaginare che questo tipo di indice cresca molto, e più grandi sono le stringhe di testo, più cresce l'indice (perché ci saranno più trigrammi). Un'altra conclusione ovvia è che mantenere questo tipo di indici può essere costoso, infatti possono influenzare notevolmente le prestazioni di INSERT e UPDATE, soprattutto se ci sono più di questi indici sulla stessa tabella, per ridurre un po' questo problema una tecnica chiamata fastupdate è stato inventato che consiste nel mantenere un elenco non ordinato di pendenti. Quindi INSERT e UPDATE invece di inserirsi nell'indice principale, lo fanno in questa struttura aggiuntiva fino a quando si verifica un VACUUM o fino a quando l'elenco in sospeso diventa più grande di work_mem. Gli svantaggi sono:1) la lettura dell'indice deve leggere anche questa struttura aggiuntiva, che può influire sulle prestazioni della query; e 2) un INSERT o UPDATE può far crescere troppo il backlog e quindi inizierà a elaborare il backlog che influenzerà tale INSERT o UPDATE e tutte le altre operazioni che si verificano contemporaneamente su quella tabella.

In conclusione; un indice GIN insieme al modulo pg_trgm può aiutare molto le prestazioni di alcune query, tuttavia non dovrebbero essere abusate in quanto possono essere un'arma a doppio taglio.