PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

unaccent() uniemożliwiający użycie indeksu w Postgres

NIEZMIENNY wariant unaccent()

Wyjaśnienie dezinformacji w obecnie zaakceptowanej, nieprawidłowej odpowiedzi :
Indeksy wyrażeń zezwalają tylko na IMMUTABLE funkcje (z oczywistych powodów) i unaccent() jest tylko STABLE . rozwiązanie zaproponowane w komentarzu jest również problematyczny. Szczegółowe wyjaśnienie i właściwe rozwiązanie za to :

W zależności od zawartości tags->name przydatne może być dodanie unaccent() do indeksu wyrażenia, ale to jest prostopadłe do pytania, dlaczego indeks nie był używany:

Rzeczywisty problem/rozwiązanie

Operator LIKE w zapytaniu jest nieznacznie błędny (najprawdopodobniej). nie chcesz zinterpretować 'Weststrasse' jako wzorzec wyszukiwania, chcesz dopasować (znormalizowany) ciąg bez zmian. Zastąp = operatora, a zobaczysz skan (mapa bitowa) indeksu z bieżącym indeksem, niezależnie zmienności funkcji unaccent() :

SELECT * FROM germany.ways
WHERE lower(tags->'name') = lower(unaccent('unaccent','Weststrasse'))

Dlaczego?

Właściwy operand LIKE to wzór . Postgres nie może używać zwykłego indeksu btree do dopasowywania wzorców ( obowiązują wyjątki ). LIKE ze zwykłym ciągiem jako wzorcem (bez znaków specjalnych) można zoptymalizować za pomocą sprawdzania równości w indeksie btree. Ale jeśli w ciągu występują znaki specjalne, to indeks jest niedostępny.

Jeśli istnieje IMMUTABLE funkcja na prawo od LIKE , można go natychmiast ocenić, a wspomniana optymalizacja jest nadal możliwa. Zgodnie z dokumentacją dotyczącą kategorii zmienności funkcji :

To samo nie jest możliwe przy mniejszej zmienności funkcji (STABLE lub VOLATILE ). Dlatego Twoje "rozwiązanie" fałszowania IMMUTABLE unaccent() wydawało się, że działa, ale tak naprawdę to nakładanie szminki na świnię.

Aby powtórzyć:

  • Jeśli chcesz pracować z LIKE i wzorców, użyj indeksu trygramu .
  • Jeśli nie chcesz pracować z LIKE i wzorców, użyj operatora równości =



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Obce/akcentowane znaki w zapytaniu sql

  2. Jak stworzyć skrypt sql schematu bazy danych postgres?

  3. Zbuduj kontener docker postgres z początkowym schematem

  4. Jak posortować obiekty w tablicy wewnątrz wartości json lub jsonb według właściwości obiektów?

  5. Wartość przesunięcia strefy czasowej serwera