Про LIKE/ILIKE в postgresql.
Постараемся избежать:
1. обсуждение индексов gin (полнотекстовый)/gist (по сложным структурам)
2. про устройство полнтекствого поиска и как можно быстро искать поговорим потом.
3. заметку, что LIKE в отличие от ILIKE может работать с индексами, правда не с gin а с b-tree и правда только в случае
4. обсуждение расширений, чтобы ILIKE все-таки заставить работать с индексами
5. и даже не будем углубляться в разницу между LIKE и ILIKE - не будем зансочивы утверждая, что в спецификации sql ILIKE никакого нет и просто напомним себе, что ILIKE - это postgres оператор аналог LIKE только к регистру не чувствительный.
Сейчас не об этом. Я про микрооптимизацию, которую порой встречаю при полнтекстовом поиске по нескольким полям.
Вместо:
можно переписать, чтобы postgres проходился по одной строке, а не по 7 отдельно, и якобы снизить нагрузку на cpu:
На самом деле нет.
Во-первых, ленивое вычисление. OR быстрее, т.к. при нахождении совпадения не идет дальше, но с null надо будет обрабатывать через COALESCE,
Во-вторых, ложное срабатывание в случае CONCAT_WS - мы получаем строку, которая может совпать и которой реально нет в бд.
В-третьих, да нет здесь никакой оптимизации. Упираемся в seq scan в обоих случаях. Не умеет Postgres b-tree индексы в случае с %value% в отличие от LIKE c 'value%'.
А как же быть:
1. Если хотим ILIKE c 'value%' и индекс скан, то нам надо использовать функциональный индекс и отказаться от ILIKE
а и условия получается такое
но тут надо быть осторожным, т.к. обычная локаль на подобии ru_RU.UTF-8 или en_US.UTF-8 может не использовать b-tree индекс для LIKE в нашем случае, а значит надо укзать text_patter_ops явно при создании индекса.
2. Если после первого пункта мы все равно хотим ILIKE, то триграммный индекс в помощь
3. Если у нас все же поиск целым словам, а жажда ILIKE нас отпустила, то мы получаем полнотекстовый поиск и соответсвенно полнотекстовый индекс.
З.Ы.: все-таки картинки ИИ генерит отстой
