У меня есть следующий запрос, который занимает очень много времени для выполнения. Мне нужно ускорить его, но я теряю информацию о том, какую технику использовать. Это запрос:Оптимизация Mysql на основе объяснения
SELECT
`User`.`id`,
`User`.`username`,
`User`.`password`,
`User`.`role`,
`User`.`created`,
`User`.`modified`,
`User`.`email`,
`User`.`other_user_id`,
`User`.`first_name`,
`User`.`last_name`,
`User`.`place_id`,
`Resume`.`id`,
`Resume`.`user_id`,
`Resume`.`other_resume_id`,
`Resume`.`other_user_id`,
`Resume`.`file_extension`,
`Resume`.`created`,
`Resume`.`modified`,
`Resume`.`is_deleted`,
`Resume`.`has_file`,
`Resume`.`is_stamped`,
`Resume`.`is_active`
FROM
`streetofwalls`.`users` AS `User`
LEFT JOIN `my_database`.`attempts` AS `Attempt`
ON (`Attempt`.`user_id` = `User`.`id` AND `Attempt`.`test_id` != 5)
LEFT JOIN `my_database`.`reports` AS `Resume`
ON (`Resume`.`user_id` = `User`.`id`)
WHERE
`Attempt`.`test_id` = 8
AND `Attempt`.`score` > 60
AND `User`.`id` IN (
SELECT
`User1`.`id`
FROM
`my_database`.`users` AS User1
LEFT JOIN `my_database`.`tags_users` AS TagUser
ON (`User1`.`id`= `TagUser`.`user_id`)
LEFT JOIN `my_database`.`tags` AS Tag
ON (`TagUser`.`tag_id`= `Tag`.`id`)
WHERE `Tag`.`id` = (8))
AND `User`.`id` NOT IN (
SELECT
`User1`.`id`
FROM
`my_database`.`users` AS User1
LEFT JOIN `my_database`.`tags_users` AS TagUser
ON (`User1`.`id`= `TagUser`.`user_id`)
LEFT JOIN `my_database`.`tags` AS Tag
ON (`TagUser`.`tag_id`= `Tag`.`id`)
WHERE `Tag`.`id` = (3))
AND `Resume`.`has_file` = 1
GROUP BY `User`.`id`
ORDER BY `Attempt`.`score` DESC;
Этот запрос генерирует следующие объяснения:
Как вы можете видеть, у меня есть несколько индексов по этому запросу. На данный момент только таблица резюме не может быть проиндексирована. Можно ли индексировать эту таблицу в контексте этого запроса? Есть ли другой способ ускорить этот запрос, о котором я не думал? Его непозволительно медленно для его намеченной функции, и у меня нет идей. Спасибо всем, кто может помочь. Пожалуйста, дайте мне знать, нужна ли какая-либо другая информация.
Чтобы быть тупым, это действительно запутанный запрос, и это должно быть исправлено до того, как вы попытаетесь его оптимизировать; Я не могу с готовностью сказать о намеченной цели. Некоторые запутывающие вещи: а) вы делаете левые соединения, но затем помещаете ограничения в предложение where, эффективно делая их внутренними объединениями. б) Я не могу с легкостью объяснить, почему вы используете GROUP BY, поскольку не используется функция агрегата, и, следовательно, полученные данные неопределенны, одна из наиболее уродливых функций MySQL. Можете ли вы предоставить образцы данных и желаемый результат? – RedFilter
Как указано в @RedFilter, предложение WHERE эффективно устраняет необходимость в LEFT JOINs в основном запросе. Кроме того, предложение WHERE предполагает, что пользователь должен иметь Tag = 8 и не должен иметь тег = 3. Это можно было бы получить более эффективным способом, который ЛЕВАЕТ СОЕДИНЯЕТ. – user2989408
Я бы обратил внимание на комментарий RedFilters ... но с точки зрения оптимизированной точки зрения, вы, судя по всему, являетесь кандидатами выбора в своем предложении where. MySQL preforms подзапросит в том, где предложения ужасно плохо, и обычно лучше всего записывать как объединение, а не в предложение where. – Twelfth