FTS non supporta LIKE
La risposta precedentemente accettata non era corretta. La ricerca full-text con i suoi indici full-text non per il LIKE
operatore, ha i suoi operatori e non funziona per stringhe arbitrarie. Funziona su parole basato su dizionari e stemming. lo fa supporta la corrispondenza dei prefissi per le parole , ma non con il LIKE
operatore:
- Ottieni una corrispondenza parziale dalla colonna TSVECTOR indicizzata GIN
Indici di trigramma per LIKE
Installa il modulo aggiuntivo pg_trgm
che fornisce classi operatore per gli indici trigram GIN e GiST per supportare tutti LIKE
e LIKE
modelli , non solo quelli ancorati a sinistra:
Esempio di indice:
CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);
Oppure:
CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);
- Differenza tra indice GiST e GIN
Esempio di query:
SELECT * FROM tbl WHERE col LIKE '%foo%'; -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%'; -- works case insensitively as well
Trigrammi? E le corde più corte?
Parole con meno di 3 lettere nei valori indicizzati funzionano ancora. Il manuale:
Si considera che ogni parola abbia due spazi preceduti e uno spazio suffisso quando si determina l'insieme di trigrammi contenuti nella stringa.
E i modelli di ricerca con meno di 3 lettere? Il manuale:
Per entrambi LIKE
e le ricerche di espressioni regolari, tieni presente che un modello senza trigrammi estraibili degenererà in una scansione dell'indice completo.
Ciò significa che le scansioni dell'indice / bitmap funzionano ancora (i piani di query per l'istruzione preparata non si rompono), semplicemente non ti compreranno prestazioni migliori. In genere nessuna grossa perdita, dal momento che le stringhe di 1 o 2 lettere sono difficilmente selettive (più di una piccola percentuale delle corrispondenze della tabella sottostante) e il supporto dell'indice non migliorerebbe le prestazioni per cominciare, perché una scansione completa della tabella è più veloce.
text_pattern_ops
per la corrispondenza del prefisso
Solo per ancorati a sinistra patterns (nessun carattere jolly iniziale) ottieni l'optimum con una classe di operatori adatta per un indice btree:text_pattern_ops
o varchar_pattern_ops
. Entrambe le funzionalità integrate di Postgres standard, nessun modulo aggiuntivo necessario. Performance simile, ma indice molto più piccolo.
Esempio di indice:
CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);
Esempio di query:
SELECT * FROM tbl WHERE col LIKE 'foo%'; -- no leading wildcard
Oppure , se dovresti eseguire il tuo database con la 'C' locale (di fatto no locale), quindi tutto viene comunque ordinato in base all'ordine dei byte e un semplice indice btree con classe operatore predefinita fa il lavoro.
Maggiori dettagli, spiegazioni, esempi e collegamenti in queste risposte correlate su dba.SE:
- Corrispondenza del modello con LIKE, SIMILAR TO o espressioni regolari in PostgreSQL
- Come viene implementato LIKE?
- Trovare rapidamente stringhe simili con PostgreSQL