Отговорът зависи от много фактори като версия на Postgres, кодиране и локал - LC_COLLATE
по-специално.
Голият израз lower(description) LIKE '%abc%'
обикновено е малко по-бързо от description ILIKE '%abc%'
, и всеки е малко по-бърз от еквивалентния регулярен израз:description ~* 'abc'
. Това има значение за последователни сканирания, при които изразът трябва да бъде оценен за всеки тестван ред.
Но за големи таблици, каквито демонстрирате в отговора си, със сигурност ще се използва индекс. За произволни шаблони (не само закотвени вляво) предлагам индекс на триграма с помощта на допълнителния модул pg_trgm
. Тогава говорим за милисекунди вместо секунди и разликата между горните изрази се нулира.
GIN и GiST индекси (с помощта на gin_trgm_ops
или gist_trgm_ops
операторни класове) поддържат LIKE
(~~
), ILIKE
(~~*
), ~
, ~*
(и още някои варианти) еднакво. С триграма GIN индекс в description
(обикновено по-голям от GiST, но по-бърз за четене), вашата заявка ще използва description ILIKE 'case_insensitive_pattern'
.
Свързано:
- Варианти на ефективността на заявката като PostgreSQL LIKE
- Подобни UTF-8 низове за поле за автоматично довършване
Основи за съвпадение на шаблони в Postgres:
- Съвпадение на образец с LIKE, SIMILAR TO или регулярни изрази в PostgreSQL
Когато работите с посочения индекс на триграма, това е типично по-практично за работа с:
description ILIKE '%abc%'
Или с независимия от главните и малки букви оператора за регулярни изрази (без %
заместващи знаци):
description ~* 'abc'
Индекс на (description)
не поддържа заявки за lower(description)
като:
lower(description) LIKE '%abc%'
И обратно.
С предикати на lower(description)
изключително , индексът на израза е малко по-добрият вариант.
Във всички останали случаи, индекс на (description)
е за предпочитане, тъй като поддържа и двете чувствителни към главни и нечувствителни предикати.