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

Hvordan indekserer man en postgres-tabel efter navn, når navnet kan være på ethvert sprog?

Hvis du ønsker at optimere vilkårlige understreng-matches, er en mulighed at bruge pg_tgrm modul . Tilføj et indeks:

CREATE INDEX table_location_name_trigrams_key ON table
  USING gin (location_name gin_trgm_ops);

Dette vil opdele "Simple Cafe" i "sim", "imp", "mpl" osv., og tilføje en post til indekset for hver trigam i hver række. Forespørgselsplanlæggeren kan derefter automatisk bruge dette indeks til understrengmønstermatches, herunder:

SELECT * FROM table WHERE location_name ILIKE '%cafe%';

Denne forespørgsel vil slå "caf" og "afe" op i indekset, finde krydset, hente disse rækker og derefter kontrollere hver række mod dit mønster. (Den sidste kontrol er nødvendig, da skæringspunktet mellem "caf" og "afe" matcher både "simpel cafe" og "usikre stilladser", mens "%cafe%" kun skal matche én). Indekset bliver mere effektivt, efterhånden som inputmønsteret bliver længere, da det kan udelukke flere rækker, men det er stadig ikke så effektivt som at indeksere hele ord, så forvent ikke en præstationsforbedring i forhold til to_tsvector .

Fangst er, at trigrammer slet ikke virker for mønstre, der er under tre tegn. Det er måske eller ikke en deal-breaker for din ansøgning.

Rediger: Jeg tilføjede først dette som en kommentar.

Jeg fik en anden tanke i går aftes, da jeg for det meste sov. Lav en cjk_chars funktion, der tager en inputstreng, regexp_matches hele CJK Unicode-intervallerne og returnerer en matrix af sådanne tegn eller NULL hvis ingen. Tilføj et GIN-indeks på cjk_chars(location_name) . Spørg derefter efter:

WHERE CASE
  WHEN cjk_chars('query') IS NOT NULL THEN
    cjk_chars(location_name) @> cjk_chars('query')
    AND location_name LIKE '%query%'
  ELSE
    <tsvector/trigrams>
  END

Ta-da, unigrams!



  1. Last Insert ID vender ikke tilbage

  2. Hvad er salt, når det forholder sig til MYSQL sha1?

  3. Fejl i MySQL ved indstilling af standardværdi for DATE eller DATETIME

  4. Sådan fungerer REGEXP_INSTR()-funktionen i MySQL