@raTaHoa

Как составить наиболее оптимальный запрос с поиском по одинаковому полю в разных таблицах PostgreSQL с сортировкой по нему в конечном результате?

БД PostgreSQL 9+

Есть несколько таблиц разных сущностей, у них есть несколько одинаковых полей (name, price, description,...).

Они через таблицу-связку объединены в один список для вывода на экран.
Эта таблица выглядит так:
CREATE TABLE section_items(
	id serial not null primary key,  
	section_id int4, -- ссылка на секцию, к которой относится привязка
	uni_id int4,     -- универсальное ID, которое ссылается на разные таблицы, в зависимости от type_item
	type_item int4,  -- хранит тип сущности, который необходимо выводить, по ней определяется к какой таблице надо обращаться за данными
	sort_num int4
);


Предположим, что есть таблица A (name, price, description, test_id, last_date_actual,...), таблица B (name, price, description, questions_id, location_position, ...), таблица C (name, price, description, webinar_url, webinar_time_start,...), и т.д.. Кол-во подобных сущностей в будущем планируется увеличивать.

Все они выводятся в похожей +- структуре на страницу, под разные структуры свой шаблон плитки. С этим проблем нет.

Теперь суть вопроса: Пользователь в строку поиска на сайте вводит фразу, по которой необходимо найти все причастные к разделу сущности, с учетом этой фразы, а так же отсортировать их по наименованию.

т.е. конечный скрипт запроса должен сформироваться в следующем виде:
select section_items.*, (/* тут предполагаю какая-нибудь функция выборки полей */) as name 
from section_items 
/*тут длинный запрос объединения и получения name из разных сущностей*/ 
order by name 
limit 12 offset 0;


Пример результата выполнения этого запроса:
пользователь ввел "обуч", в первом разделе и сформировалась табличка:
id | section_id | uni_id | type_item | name
-------------------------------------------------
2 | 1 | 24 | 3 | Вебинар по обучению игре на гитаре
15 | 1 | 117 | 1 | Курс обучения игры в шахматы
25 | 1 | 14 | 1 | Курс обучения ментальной математике
116 | 1 | 24 | 2 | Тест по обучению программированию
....


Все это дело еще разбивается по странично, т.е. надо это учитывать.
Сейчас эту задачу решаю несколькими запросами, и состыковкой данных уже скриптом на стороне сервера.
Но боюсь, что это не самый оптимальный подход к решению подобной задачи, к тому же для сортировки по наименованию приходиться получать все сущности, и разбивать по странично этот массив, получая ID-ы, по которым делается еще один запрос, для правильной пагинации движка.

На мой взгляд, БД быстрее и с меньшим потреблением ресурсов, могла бы собрать эту таблицу, но я не силен в настолько сложных SQL-скриптах, потому хотел узнать, возможно ли составить нужный мне select-запрос, который бы выполнился за 1 обращение/транзакцию, и если можно, то как и с применением каких функций, как он вообще мог бы выглядеть?
  • Вопрос задан
  • 272 просмотра
Пригласить эксперта
Ответы на вопрос 2
Athanor
@Athanor
Лайк + Решение: не жмись, нажми
Рекомендую приглядеться к materialized view, как уже советовали ранее.
Особенность в том, что по полю для поиска name в materialized view вы сможете посторить gist/gin index и пользоваться быстрым поиском по %like% (см. https://postgrespro.ru/docs/postgrespro/9.5/pgtrgm...

Обратите внимание, что materialized view необходимо обновлять вручную, периодически выполняя команду
REFRESH MATERIALIZED VIEW mymatview;
Ответ написан
Комментировать
@Arseniy_K
Храните необходимые поля для поиска в той же смежной таблице или во вьюхах https://www.postgresql.org/docs/12/rules-materiali... https://www.postgresql.org/docs/12/rules-views.html
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы