Svaret beror på många faktorer som Postgres version, kodning och språk - LC_COLLATE
i synnerhet.
Det blotta uttrycket lower(description) LIKE '%abc%'
är vanligtvis lite snabbare än description ILIKE '%abc%'
, och båda är lite snabbare än motsvarande reguljära uttryck:description ~* 'abc'
. Detta är viktigt för sekventiella skanningar där uttrycket måste utvärderas för varje testad rad.
Men för stora tabeller som du visar i ditt svar skulle man säkert använda ett index. För godtyckliga mönster (inte bara vänsterförankrade) föreslår jag ett trigramindex med hjälp av tilläggsmodulen pg_trgm
. Då pratar vi om millisekunder istället för sekunder och skillnaden mellan ovanstående uttryck försvinner.
GIN- och GiST-index (med hjälp av gin_trgm_ops
eller gist_trgm_ops
operatörsklasser) stöder LIKE
(~~
), ILIKE
(~~*
), ~
, ~*
(och några fler varianter) likadana. Med ett trigram GIN-index på description
(vanligtvis större än GiST, men snabbare för läsning), din fråga skulle använda description ILIKE 'case_insensitive_pattern'
.
Relaterat:
- PostgreSQL LIKE-frågeprestandavarianter
- Liknande UTF-8-strängar för autoslutförandefält
Grunderna för mönstermatchning i Postgres:
- Mönstermatchning med LIKE, SIMILAR TO eller reguljära uttryck i PostgreSQL
När du arbetar med nämnda trigramindex är det vanligtvis mer praktiskt att arbeta med:
description ILIKE '%abc%'
Eller med den skiftlägesokänsliga regexp-operatorn (utan %
jokertecken):
description ~* 'abc'
Ett index på (description)
stöder inte frågor på lower(description)
gillar:
lower(description) LIKE '%abc%'
Och vice versa.
Med predikat på lower(description)
exklusivt , uttrycksindex är det något bättre alternativet.
I alla andra fall, ett index på (description)
är att föredra eftersom det stöder båda skiftlägeskänsliga och -okänsliga predikat.