Написание запроса, связывающего несколько таблиц

Есть несколько связанных таблиц. В одной из них довольно большое количество записей (порядка 2млн). Необходимо написать запрос, выбирающий конкретные записи в определенный период.

База данных MariaDB 10.8.3

Таблицы (опущу неважные поля):

1. events (id, group_id, client_id, work_id, date) - занятия
2. works (id, schedule_id) - работы в расписании
3. schedules (id, user_id) - расписания
4. users (id, department) - Преподаватели
5. groups (id) - Учебные группы
6. clients (id, last_name, first_name, middle_name, birthdate) - Студенты
7. client_group (client_id, group_id) - Студенты в группе

Внешние ключи по всем id настроены. Необходимо выбрать всех студентов (clients), у которых были занятия в определенный период (events.date) в определенном учебном корпусе (users.department). Занятия могут быть как в составе группы (тогда выбираются студенты, находящиеся в тех группах, id которых указаны в events.group_id), так и индивидуальные (в этом случае выбираются те клиенты, id которых указаны в events.client_id).

Я составил такой запрос:

select distinct clients.id, clients.last_name, clients.first_name, clients.middle_name, clients.birthdate
from clients
  join events on clients.id = events.client_id
  join works on events.work_id = works.id
  join schedules on works.schedule_id = schedules.id
  join users on schedules.user_id = users.id
where users.department = 98
  and events.client_id is not null
  and events.date between '2022-09-01' and '2022-11-14'

union

select distinct clients.id, clients.last_name, clients.first_name, clients.middle_name, clients.birthdate
from clients
  join client_group on clients.id = client_group.client_id
  join events on client_group.group_id = events.group_id
  join works on events.work_id = works.id
  join schedules on works.schedule_id = schedules.id
  join users on schedules.user_id = users.id
where users.department = 98
  and events.group_id is not null
  and events.date between '2022-09-01' and '2022-11-28'
order by last_name, first_name

limit 50 offset 0

Такой запрос у меня занимает порядка 2 минут. Я подозреваю, что это может быть либо из-за объединения двух запросов uniun-ом (хотя по отдельности они также долго выполняются, в районе минуты), либо из-за неверных индексов.

Индексы у меня такие:

clients_name_index (last_name(20), first_name(20), middle_name(20), birthdate)

client_group_client_id_group_id_index (client_id, group_id)
client_group_client_id_foreign (client_id)
client_group_group_id_foreign (group_id)

users_department_index (department)

schedules_user_id_foreign (user_id)

works_schedule_id_foreign (schedule_id)

events_date_index (date)
events_client_id_foreign (client_id)
events_group_id_foreign (group_id)
events_work_id_foreign (work_id)

Можно ли как-то переписать данный запрос, чтобы ускорить его выполнение? Количество записей в таблицах: events ~ 2 млн clients ~ 300 000 groups ~ 80 000 Общий объём БД ~ 2 Гб


Ответы (0 шт):