Как я могу оптимизировать этот запрос?
Вопрос
Как я могу оптимизировать этот запрос?Кажется, должен быть гораздо более простой способ сделать это.Цель состоит в том, чтобы его по-прежнему можно было легко превратить в оператор удаления.
SELECT * FROM team
WHERE team_id IN (
SELECT team_id
FROM (
SELECT team.team_id, (
SELECT COUNT(*)
FROM signup
WHERE signup.team_id = team.team_id
) AS members
FROM team, schedule, event
WHERE team.schedule_id = schedule.schedule_id
AND schedule.event_id = event.event_id
AND event.event_id =183) AS t
WHERE members = 0
)
Решение
Быстрый взгляд на этот запрос дает мне следующее:
select
t.*
from
team t
inner join schedule s on t.schedule_id = s.schedule_id
inner join event e on s.event_id = e.event_id
left outer join signup sp on t.team_id = sp.team_id
where
e.event_id = 183
and sp.team_id is null
Похоже, вы пытаетесь найти все команды, которые участвуют в мероприятии, но не указаны в таблице регистрации.Это точно?
Также я хотел отметить, что выполнять соединения будет быстрее, чем кучу подзапросов, особенно если подзапросы зависят от каждой строки (в вашем случае они зависят).
Ваше здоровье,
Эрик
Другие советы
Комментируя запрос Эрика в этой теме, я бы рекомендовал (исходя из моего опыта работы с mssqlserver) вместо этого использовать экзистенциальную проверку.Это (1) сделает ваше намерение более ясным и (2) даст оптимизатору возможность прекратить поиск соответствующего team_id после того, как будет найден первый (поскольку >=1 совпадающая строка приводит к тому, что экзистенциальная проверка оказывается ложной).Например.
Выберите t. * из группы Tean T Внутренний график соединения S на t.schedule_id = s.schedule_id inner gin event e on s.event_id = e.event_id, где e.event_id = 183 и не существует (выберите * от регистрации, где team_id = t. team_id)
Но, возможно, есть проблемы с производительностью, специфичные для MySQL.