FTS stöder inte LIKE
Det tidigare accepterade svaret var felaktigt. Fulltextsökning med dess fulltextindex är inte för LIKE
operatör alls, den har sina egna operatörer och fungerar inte för godtyckliga strängar. Det fungerar på ord baserad på ordböcker och stemming. Det gör stöder prefixmatchning för ord , men inte med LIKE
operatör:
- Få partiell matchning från GIN-indexerad TSVECTOR-kolumn
Trigramindex för LIKE
Installera tilläggsmodulen pg_trgm
som tillhandahåller operatörsklasser för GIN- och GiST-trigramindex för att stödja alla LIKE
och ILIKE
mönster , inte bara vänsterförankrade:
Exempelindex:
CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);
Eller:
CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);
- Skillnad mellan GiST och GIN-index
Exempelfråga:
SELECT * FROM tbl WHERE col LIKE '%foo%'; -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%'; -- works case insensitively as well
Trigram? Hur är det med kortare strängar?
Ord med färre än 3 bokstäver i indexerade värden fungerar fortfarande. Manualen:
Varje ord anses ha två mellanslag före och ett mellanslag vid fastställande av uppsättningen trigram i strängen.
Och sökmönster med mindre än 3 bokstäver? Manualen:
För båda
LIKE
och sökningar med reguljära uttryck, kom ihåg att ett mönster utan extraherbara trigram kommer att degenerera till en fullindexskanning.
Det betyder att index-/bitmappsindexsökningar fortfarande fungerar (frågeplaner för förberedda uttalanden kommer inte att gå sönder), det kommer bara inte att ge dig bättre prestanda. Vanligtvis ingen stor förlust, eftersom strängar på 1 eller 2 bokstäver knappast är selektiva (mer än några procent av de underliggande tabellmatchningarna) och indexstöd inte skulle förbättra prestandan till att börja med, eftersom en fullständig tabellsökning är snabbare.
text_pattern_ops
för prefixmatchning
För bara vänsterankrade mönster (inget inledande jokertecken) får du det optimala med en lämplig operatorklass för ett btree-index:text_pattern_ops
eller varchar_pattern_ops
. Båda inbyggda funktionerna i standard Postgres, ingen extra modul behövs. Liknande prestanda, men mycket mindre index.
Exempelindex:
CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);
Exempelfråga:
SELECT * FROM tbl WHERE col LIKE 'foo%'; -- no leading wildcard
Eller , om du skulle köra din databas med 'C' locale (effektivt nej locale), så sorteras allt enligt byteordning ändå och ett vanligt btree-index med standardoperatörsklass gör jobbet.
Mer detaljer, förklaringar, exempel och länkar i dessa relaterade svar på dba.SE:
- Mönstermatchning med LIKE, SIMILAR TO eller reguljära uttryck i PostgreSQL
- Hur implementeras LIKE?
- Snabbt att hitta liknande strängar med PostgreSQL