sql >> Databáze >  >> RDS >> PostgreSQL

Variace výkonu dotazů PostgreSQL LIKE

FTS nepodporuje ILIKE

Dříve přijatá odpověď byla nesprávná. Fulltextové vyhledávání s fulltextovými indexy není pro ILIKE operátor vůbec, má své operátory a nefunguje pro libovolné řetězce. Funguje na slovech založené na slovnících a pramenech. dělá podpora porovnání předpon u slov , ale ne pomocí ILIKE operátor:

  • Získejte částečnou shodu ze sloupce TSVECTOR indexovaného GIN

Trigram indexy pro ILIKE

Nainstalujte přídavný modul pg_trgm který poskytuje třídy operátorů pro indexy trigramů GIN a GiST pro podporu všech ILIKE a ILIKE vzory , nejen ty ukotvené vlevo:

Příklad indexu:

CREATE INDEX tbl_col_gin_trgm_idx  ON tbl USING gin  (col gin_trgm_ops);

Nebo:

CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);
  • Rozdíl mezi indexem GiST a GIN

Příklad dotazu:

SELECT * FROM tbl WHERE col LIKE '%foo%';   -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%';  -- works case insensitively as well

Trigramy? A co kratší struny?

Slova s ​​méně než 3 písmeny v indexovaných hodnotách stále fungují. Manuál:

Při určování sady trigramů obsažených v řetězci se má za to, že každé slovo má dvě předpony a jednu příponu.

A hledat vzory s méně než 3 písmeny? Manuál:

Pro oba ILIKE a vyhledávání regulárních výrazů, mějte na paměti, že vzor bez extrahovatelných trigramů se zvrhne na sken s úplným indexem.

To znamená, že skenování indexu / bitmapového indexu stále funguje (plány dotazů pro připravený příkaz se nezlomí), jen vám nekoupí lepší výkon. Obvykle žádná velká ztráta, protože 1- nebo 2písmenné řetězce jsou stěží selektivní (více než několik procent podkladových tabulek se shoduje) a podpora indexů by zpočátku nezlepšila výkon, protože úplné prohledání tabulky je rychlejší.


text_pattern_ops pro párování prefixů

Pouze pro ukotvení vlevo vzory (bez úvodního zástupného znaku) získáte optimum s vhodnou třídou operátorů pro index btree:text_pattern_ops nebo varchar_pattern_ops . Obě vestavěné funkce standardního Postgresu, není potřeba žádný další modul. Podobný výkon, ale mnohem menší index.

Příklad indexu:

CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);

Příklad dotazu:

SELECT * FROM tbl WHERE col LIKE 'foo%';  -- no leading wildcard

Nebo , pokud byste měli provozovat databázi s 'C' národní prostředí (ve skutečnosti ne locale), pak se stejně vše seřadí podle pořadí bajtů a práci udělá prostý index btree s výchozí třídou operátorů.

Další podrobnosti, vysvětlení, příklady a odkazy v těchto souvisejících odpovědích na dba.SE:

  • Shoda vzorů s LIKE, SIMILAR TO nebo regulárními výrazy v PostgreSQL
  • Jak se implementuje LIKE?
  • Rychlé nalezení podobných řetězců pomocí PostgreSQL


  1. Kde změnit hodnotu lower_case_table_names=2 v systému Windows xampp

  2. Jak nastavit, aby operátor SQLite LIKE rozlišoval malá a velká písmena

  3. SQL rozdělit hodnoty do více řádků

  4. SQLite JSON_SET()