Svaret afhænger af mange faktorer som Postgres version, kodning og lokalitet - LC_COLLATE
især.
Det blotte udtryk lower(description) LIKE '%abc%'
er typisk en smule hurtigere end description ILIKE '%abc%'
, og begge er en smule hurtigere end det tilsvarende regulære udtryk:description ~* 'abc'
. Dette har betydning for sekventielle scanninger, hvor udtrykket skal evalueres for hver testet række.
Men for store tabeller, som du viser i dit svar, ville man helt sikkert bruge et indeks. For vilkårlige mønstre (ikke kun venstreforankrede) foreslår jeg et trigramindeks ved hjælp af det ekstra modul pg_trgm
. Så taler vi om millisekunder i stedet for sekunder, og forskellen mellem ovenstående udtryk ophæves.
GIN- og GiST-indekser (ved hjælp af gin_trgm_ops
eller gist_trgm_ops
operatørklasser) understøtter LIKE
(~~
), ILIKE
(~~*
), ~
, ~*
(og nogle flere varianter) ens. Med et trigram GIN-indeks på description
(typisk større end GiST, men hurtigere til læsning), vil din forespørgsel bruge description ILIKE 'case_insensitive_pattern'
.
Relateret:
- PostgreSQL LIKE forespørgselsydeevnevariationer
- Lignende UTF-8-strenge for autofuldførelsesfelt
Grundlæggende om mønstertilpasning i Postgres:
- Mønstermatching med LIKE, SIMILAR TO eller regulære udtryk i PostgreSQL
Når du arbejder med nævnte trigramindeks, er det typisk mere praktisk at arbejde med:
description ILIKE '%abc%'
Eller med den regexp-operator, der ikke skelner mellem store og små bogstaver (uden %
jokertegn):
description ~* 'abc'
Et indeks på (description)
understøtter ikke forespørgsler på lower(description)
som:
lower(description) LIKE '%abc%'
Og omvendt.
Med prædikater på lower(description)
eksklusivt , er udtryksindekset den lidt bedre mulighed.
I alle andre tilfælde et indeks på (description)
er at foretrække, da den understøtter begge dele bogstavfølsomme og -ufølsomme prædikater.