FTS biedt geen ondersteuning voor LIKE
Het eerder geaccepteerde antwoord was onjuist. Zoeken in volledige tekst met zijn volledige tekstindexen is niet voor de LIKE
operator helemaal niet, het heeft zijn eigen operators en werkt niet voor willekeurige strings. Het werkt op woorden gebaseerd op woordenboeken en stammen. Het doet ondersteuning van prefix-overeenkomst voor woorden , maar niet met de LIKE
operator:
- Gedeeltelijke overeenkomst ophalen uit GIN-geïndexeerde TSVECTOR-kolom
Trigram-indexen voor LIKE
Installeer de extra module pg_trgm
die operatorklassen biedt voor GIN- en GiST-trigramindexen om alle LIKE
te ondersteunen en ILIKE
patronen , niet alleen links verankerde:
Voorbeeldindex:
CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);
Of:
CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);
- Verschil tussen GiST en GIN-index
Voorbeeldvraag:
SELECT * FROM tbl WHERE col LIKE '%foo%'; -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%'; -- works case insensitively as well
Trigrammen? Hoe zit het met kortere snaren?
Woorden met minder dan 3 letters in geïndexeerde waarden werken nog steeds. De handleiding:
Bij het bepalen van de reeks trigrammen in de tekenreeks wordt aangenomen dat elk woord twee spaties als prefix heeft en één spaties.
En zoekpatronen met minder dan 3 letters? De handleiding:
Voor beide
LIKE
en reguliere expressies, houd er rekening mee dat een patroon zonder extraheerbare trigrammen zal degenereren tot een volledige indexscan.
Dit betekent dat de index-/bitmap-indexscans nog steeds werken (queryplannen voor voorbereide instructies zullen niet kapot gaan), u krijgt er gewoon geen betere prestaties mee. Meestal geen groot verlies, aangezien strings van 1 of 2 letters nauwelijks selectief zijn (meer dan een paar procent van de onderliggende tabelovereenkomsten) en indexondersteuning zou de prestaties om te beginnen niet verbeteren, omdat een volledige tabelscan sneller is.
text_pattern_ops
voor prefix matching
Voor slechts links verankerd patronen (geen leidende wildcard) krijg je het optimum met een geschikte operatorklasse voor een btree-index:text_pattern_ops
of varchar_pattern_ops
. Beide ingebouwde functies van standaard Postgres, geen extra module nodig. Vergelijkbare prestaties, maar veel kleinere index.
Voorbeeldindex:
CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);
Voorbeeldvraag:
SELECT * FROM tbl WHERE col LIKE 'foo%'; -- no leading wildcard
Of , als u uw database zou moeten draaien met de 'C' locale (in feite nee locale), dan wordt alles toch gesorteerd volgens bytevolgorde en een gewone btree-index met standaard operatorklasse doet het werk.
Meer details, uitleg, voorbeelden en links in deze gerelateerde antwoorden op dba.SE:
- Patroon komt overeen met LIKE, VERGELIJKBAAR MET of reguliere expressies in PostgreSQL
- Hoe wordt LIKE geïmplementeerd?
- Snel vergelijkbare strings vinden met PostgreSQL