PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

unaccent() предотвратява използването на индекс в Postgres

НЕИЗМЕНЕН вариант на unaccent()

За изясняване на дезинформацията в текущо приет, неправилен отговор :
Индексите на изрази позволяват само IMMUTABLE функции (по очевидни причини) и unaccent() е само STABLE . решението, което предложихте в коментара също е проблематично. Подробно обяснение и правилно решение за това :

В зависимост от съдържанието на tags->name може да е полезно да добавите unaccent() към индекса на израза, но това е ортогонално на въпроса защо индексът не е бил използван:

Действителен проблем/решение

Операторът LIKE във вашата заявка е леко грешно (най-вероятно). Вие ненеправите искате да интерпретирате 'Weststrasse' като модел за търсене, искате да съвпаднете с (нормализирания) низ такъв, какъвто е. Заменете с = оператор и ще видите сканиране на (растерен) индекс с текущия ви индекс, независимо на променливостта на функцията на unaccent() :

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

Защо?

Десният операнд на LIKE е модел . Postgres не може да използва обикновен btree индекс за съвпадение на шаблони ( важат изключения ). LIKE с обикновен низ като шаблон (без специални знаци) може да се оптимизира с проверка за равенство на индекса btree. Но ако в низа има специални знаци, това индексът е изчерпан.

Ако има IMMUTABLE функция отдясно на LIKE , то може да бъде оценено незабавно и споменатата оптимизация все още е възможна. Според документация относно Категории променливост на функции :

Същото не е възможно с по-малка волатилност на функцията (STABLE или VOLATILE ). Ето защо вашето "решение" за фалшифициране на IMMUTABLE unaccent() изглеждаше, че работи, но всъщност е да сложиш червило на прасе.

За да повторя:

  • Ако искате да работите с LIKE и модели, използвайте триграмен индекс .
  • Ако не искате да работите с LIKE и шаблони, използвайте оператора за равенство =



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres 9.4 jsonb масив като таблица

  2. PostgreSQL:как да конвертирам от епоха на Unix към днешна дата?

  3. Ограничението за дълбочина на стека е надвишено в PostgresQL (след тригер за изтриване)

  4. UPDATE с jsonb_set() засяга само един обект във вложен масив

  5. Как Atan() работи в PostgreSQL