В вашем примере вы захотите создать индекс для выражения (name || (cars ->> 'values') || surname)
. Однако сам ваш пример не имеет смысла. Это действительный SQL, но с какой стати вы захотите это сделать? Почему вы сравниваете английское предложение со строкой, состоящей из чьего-то полного имени, но с серединой капли JSON? Это важно, потому что в вашем примере только одна строка, поэтому индекс не имеет значения. Поэтому мы должны экстраполировать ваш пример на большое количество строк, где будет иметь значение индекс. Но поскольку это не имеет никакого смысла в реальном мире, как мы можем разумно экстраполировать его?
Кроме того, я не понимаю, какой тип индекса лучше - GIN или GiST,Я читал, что GIN обычно лучше для обычного полнотекстового поиска, но GiST лучше для поиска триграмм. Это правильно?
Не совсем так по моему опыту. Индексы триграмм GiST основаны на сигнатурах, где каждая триграмма устанавливает бит в сигнатуре. Но триграмм гораздо больше, чем битов, поэтому они сильно перегружены. Эти типы индексов работают хорошо только тогда, когда они немного заполнены. (Но трудно сказать, что означает «малонаселенный» заранее, другие «пробуют это с вашим реальным набором данных и видят».) Учитывая их непредсказуемость, я избегаю индексов GiST, если для них нет явной выгоды, которую яздесь не вижу.
Учитывая ваш запрос, вы можете использовать любой вид индекса, но его придется написать по-другому. Кроме того, сомнительно, что любой индекс помог бы, потому что в
similarity(x,exp) > 0.05
отсечение 0,05 настолько слабое, что несколько строк, вероятно, будут отклонены индексом.
Если вы имеличем выше значение отсечки, например 0,5, то с индексом GIN это будет выглядеть следующим образом:
set pg_trgm.similarity_threshold = 0.5;
select ... from test_table where x % exp order by x <-> exp ;
Это позволит извлечь все достаточно похожие, а затем отсортировать их по расстоянию. Если достаточно мало вещей "достаточно похожи", это дает довольно хорошую производительность (а если нет, вам следует вернуться к своему выбору pg_trgm.simility_threshold). Как говорит Лоренц Альбе, с помощью индекса GiST вы можете извлечь уже упорядоченные строки и затем остановиться после достижения LIMIT, но в отсутствие предложения LIMIT это не имеет значения.