Написание запроса, связывающего несколько таблиц
Есть несколько связанных таблиц. В одной из них довольно большое количество записей (порядка 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 Гб