оптимизация поисковых запросов PG SQL SQL для больших текстов ('лайки', полнотекстовый поиск, ...) - PullRequest
1 голос
/ 18 июня 2020

У нас есть программное решение, которым пользуются более 200 клиентов. Недавно мы перешли на pg sql, потому что наша бывшая база данных слишком медленно обрабатывала поисковые запросы, которые используют наши клиенты.

Наша база данных выглядит так:

ТАБЛИЦА A

 1. ID
(+ some other fields which aren't important here)

ТАБЛИЦА B

Эта таблица используется для хранения «данных» по элементам в таблице A. Это индивидуально для каждого покупателя. Например, «Тип» может быть «ИМЯ КЛИЕНТА» и значение «АЗЕРТИ». Одна запись в ТАБЛИЦЕ A может иметь бесконечное количество записей в ТАБЛИЦЕ B. Обычно одна запись в таблице A имеет от 5 до 10 записей в таблице B.

1. ID TABLE A
 2. TYPE
 3. VALUE

TABLE C

 1. TABLE A ID
 2. VERSIONNR
 3. DESCRIPTION

Этот файл имеет различные версии записей в ТАБЛИЦЕ A. Каждая из этих версий имеет расширенное описание. Это может быть от 0 до бесконечности.

Наша проблема: наших клиентов используют при поиске «в стиле Google». Например: они набирают «АЗЕРТИ», и мы показываем все записи из ТАБЛИЦЫ А, где ИД ТАБЛИЦЫ A:

  • «АЗЕРТИ» находится в описании самой последней версии ТАБЛИЦЫ C
  • 'AZERTY' находится в одном из значений ТАБЛИЦЫ B

Дополнительная проблема: этот поисковый запрос содержит 'содержит'. Если они ищут "ZER", они также должны найти записи с "AZERTY" в нем. Множественные аргументы - это «И», если они ищут «ZER 123», нам нужно показать все записи, в которых описание соответствует «ZER» и «123» или значения соответствуют «ZER» и «123».

Что мы уже сделали:

  • Существует опция, при которой пользователь может проверить, хочет ли он выполнить поиск по описанию или нет. Мы советуем им искать только значения и использовать описание только в случае необходимости.
  • Мы делаем несколько потоков поиска в базе данных для одного поискового запроса, потому что поиск по всем документам сразу займет слишком много времени. .
  • Некоторое время go, на нашем бывшем медленном движке базы данных, мой коллега сделал «таблицы поиска», в основном это таблица, которая содержит все значения в ТАБЛИЦЕ A ID, поэтому нет необходимость любого соединения в запросе SQL при поиске. Это выглядит так:

ТАБЛИЦА D

  • ИДЕНТИФИКАТОР ТАБЛИЦЫ
  • ЗНАЧЕНИЯ (все значения из ТАБЛИЦЫ B для этого ИД ТАБЛИЦЫ A, разделенные символом '')
  • ОПИСАНИЕ (описание самой последней версии для этой ТАБЛИЦЫ ID)

Пример записи:

- 1
- ZER 123 CLIENT NAME NUMBER 7856 jsdfjklf 4556423
- DESCRIPTION CAN BE VERY LONG.

Если покупатель ищет 'ZER 123' превращается в: «выберите TABLE_A_ID из TABLE_D, где такие значения, как«% ZER% »и значения, например,«% 123% »»

Важно: некоторые из наших клиентов имеют много записей в ТАБЛИЦЕ A. + 5.000.000, что означает, что в ТАБЛИЦЕ B много записей (+/- 50.000.000). Большинство наших клиентов имеют от 300 000 до 500 000 записей в ТАБЛИЦЕ A.

Мои вопросы:

  • Есть ли лучший / более быстрый способ поиска по всем значениям, чем это таблица поиска? Без таблицы поиска мне пришлось бы выполнять объединение для каждого '' в аргументе поиска клиента, что будет работать слишком медленно (я думаю?), Если у них много записей в ТАБЛИЦЕ A. Например:

    выберите ID из TABLE_A INNER JOIN TABLE_B Sub1 ON TABLE_A.ID = Sub1.TABLE_A_ID и Sub1.VALUE, например, '% ZER%' INNER JOIN TABLE_B Sub2 на FILE_A.ID = Sub2.TABLE_A_ID и Sub2.VALUE, например, '% 123%'

  • Я взглянул на полнотекстовый поиск в PG SQL. Я не думаю, что смогу использовать его, так как вы не можете использовать его как (= 'contains')?

  • Есть ли какой-либо индекс, который я могу использовать для значений (ФАЙЛ B или файл поиска ) и описание (ФАЙЛ C или файл поиска) для ускорения поиска? Я читал об этом и не думаю, что они есть, потому что индексы не используются при поиске с "вроде '% ZER%'"?

Надеюсь, я объяснил это ясно. Заранее спасибо!

1 Ответ

1 голос
/ 19 июня 2020

Ваша терминология сбивает с толку, но я предполагаю, что вы имеете в виду «таблицы», когда пишете «файлы».

Вы не можете разумно искать в нескольких таблицах с помощью одного запроса, но вы можете искать в нескольких столбцах одну таблицу одновременно.

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

...