2013-07-22 3 views
0

У меня есть стол в постгерсе 8.1 db с информацией о приблизительно 370 000 клиентов. В эту таблицу входят поля sn (фамилия) и gn (данное имя). Я бы хотел, чтобы пользователи могли искать имена пользователей с помощью формы или просто. Моя первая попытка построить запрос было так:Как реализовать поиск полного имени в postgres

SELECT sn || ', ' || gn as name from users 
WHERE sn || ' ' || gn like '%Johnson David%' 
or gn || ' ' || sn like '%Johnson David%' 

Это работало хорошо, но довольно медленно, с тактовой частотой 600/623 мс. Чтобы оптимизировать, я создал индекс только для поля sn, так как я догадался, что поле gn будет содержать столько дублирования, что бесполезно для индексирования. К сожалению, индексная фамилия вообще не улучшала производительность, поскольку запрос не использовал индекс.

Seq Scan on users (cost=0.00..18296.06 rows=1 width=64) (actual time=57.935..588.755 rows=8 loops=1)

Я думаю, что причиной этого является то, что описано в this thread. Я рассмотрел использование многоколоночного индекса, но я догадался, что это будет означать, что я мог бы искать только один из двух стилей, о которых я упоминал выше, то есть, но не обоих.

Я также рассмотрел возможность создания полного текстового индекса, но он кажется непригодным для значений имени, поскольку я получаю много последствий и так далее, что не имеет значения. Есть ли у кого-нибудь предложения по стратегии индексирования? Похоже, это должно быть довольно распространенным случаем.

ответ

3

Он не будет использовать индекс, так как вы используете подстановочный знак в начале строки «% ....». Это не сработает. Рассмотрим usingtrigrams. Кроме того, вы можете использовать функции f ull text search. Оба этих метода потребуют более новой версии Postgres. Вы должны обновлять в любом случае. 8.1 - это старомодный камень, не поддерживаемый, а новые версии будут не только быстрее, но и дать вам больше возможностей для работы с тем, что вы хотите.

+0

Trigrams кажется хорошим решением, но мои коллеги не очень увлекаются обновлением PostGres, так как мы могли бы нарушить некоторые из наших других кодов. –

0

Создайте индекс для полного вычисленного выражения. Это все равно приведет к сканированию индекса, но выражение будет предварительно вычислено, а индекс намного меньше всей таблицы.

+0

Можете ли вы привести пример синтаксиса? Я не понимаю, что вы подразумеваете под полным вычисленным выражением. –

+1

Sry о том, чтобы быть слишком расплывчатым. Создайте индекс для вычисленных столбцов для ('sn || '' || gn',' gn || '' || sn'). Этот индекс все равно не позволит искать, но его можно использовать для более быстрого сканирования. Если perf достаточно хорош, это простое решение. – usr

+0

hm, по какой-то причине это дает мне синтаксическую ошибку 'ERROR: синтаксическая ошибка в или рядом с" || "'. Возможно, postgres 8.1 не принимает конкатенацию в создании индекса? Будет ли работать над выполнением CREATE INDEX для пользователей (sn, gn)? –

Смежные вопросы