onveranderlijke variant van unaccent()
Ter verduidelijking van de verkeerde informatie in het momenteel geaccepteerd, onjuist antwoord
:
Expressie-indexen staan alleen IMMUTABLE
toe functies (om voor de hand liggende redenen) en unaccent()
is alleen STABLE
. De oplossing die je in de opmerking hebt voorgesteld is ook problematisch. Gedetailleerde uitleg en een juiste oplossing daarvoor :
Afhankelijk van de inhoud van tags->name
het kan handig zijn om unaccent()
. toe te voegen naar de uitdrukkingsindex, maar dat staat haaks op de vraag waarom de index niet werd gebruikt:
Eigenlijk probleem / oplossing
De operator LIKE
in uw zoekopdracht is subtiel fout (meest waarschijnlijke). Je doet niet als je 'Weststrasse' wilt interpreteren als zoekpatroon, wil je de (genormaliseerde) string as is matchen. Vervang door de =
operator, en u ziet een (bitmap) indexscan met uw huidige index, ongeacht van de functie volatiliteit van unaccent()
:
SELECT * FROM germany.ways
WHERE lower(tags->'name') = lower(unaccent('unaccent','Weststrasse'))
Waarom?
De juiste operand van LIKE
is een patroon . Postgres kan geen gewone btree-index gebruiken voor patroonovereenkomst ( uitzonderingen zijn van toepassing
). Een LIKE
met een gewone string als patroon (geen speciale tekens) kan worden geoptimaliseerd met een gelijkheidscontrole op de btree-index. Maar als er speciale tekens in de tekenreeks staan, dit index is uit.
Als er een IMMUTABLE
. is functie rechts van LIKE
, het kan onmiddellijk worden geëvalueerd en de genoemde optimalisatie is nog steeds mogelijk. Per documentatie over Functievolatiliteitscategorieën
:
Hetzelfde is niet mogelijk met een lagere functievolatiliteit (STABLE
of VOLATILE
). Dat is de reden waarom uw "oplossing" van het faken van een IMMUTABLE unaccent()
leek te werken, maar het is echt lippenstift op een varken aanbrengen.
Om te herhalen:
- Als je wilt werken met
LIKE
en patronen, gebruik een trigram index . - Als je niet wilt werken met
LIKE
en patronen, gebruik de equality operator=