sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL LIKE prestatievariaties voor query's

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


  1. MySQL selecteert snel 10 willekeurige rijen uit 600K rijen

  2. Een belangrijke wijziging in Extended Events in SQL Server 2012

  3. Gegevens importeren uit Excel-spreadsheet of CVS in MySQL

  4. Resultaten van twee query's combineren in een enkele dataset