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.