Улучшение оптимизатора запросов в MySQL 8.0.17 (по сравнению с 8.0.16)

Минорные релизы MySQL 8 совсем не минорные и у этого есть как минусы (в случае проблем откатиться обратно на предыдущий минорный релиз не выйдет), так и плюсы, т.к. в них появляются новые фишки и улучшения.

В 8.0.17 к примеру завезли оптимизацию запросов с NOT EXISTS:

The optimizer now transforms a WHERE condition having NOT IN (subquery)NOT EXISTS (subquery)IN (subquery) IS NOT TRUE, or EXISTS (subquery) IS NOT TRUE internally into an antijoin, thus removing the subquery.

Пример, имеем запрос:

SELECT task.TaskID
FROM contact
INNER JOIN login ON login.LoginID = contact.LoginID
INNER JOIN task ON task.TaskID = contact.TaskID
LEFT OUTER JOIN taskstar ON taskstar.TaskID = task.TaskID AND taskstar.LoginID = 858636
INNER JOIN taskaccess accesslogined ON task.TaskID = accesslogined.TaskID AND accesslogined.LoginID = 858636
WHERE 1
AND contact.ContactBool_1 = 0
AND contact.ContactSpam = 0
AND task.TaskType = 4
AND contact.ContactIsDeleted = 0
AND task.TaskIsDeleted = 0
AND (NOT EXISTS(SELECT 1
FROM task
WHERE ClientID = contact.ContactID
AND task.TaskIsDeleted = 0
AND (task.TaskType = 0)
AND task.TaskStatusSetID = 57450)
)
GROUP BY task.TaskID
ORDER BY task.TaskID
LIMIT 0,5

Выполняем его в MySQL 8.0.16 и получаем:

5 rows in set (1 min 9.92 sec)

Больше минуты, совсем некомфортно.
Обновляем MySQL и выполняем его же в 8.0.17:

5 rows in set (1.02 sec)

Профит 🙂

Добавить комментарий