Улучшение оптимизатора запросов в 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)

Профит 🙂

Несколько фактов про Redis #painisinstructional

  1. Пустая строка — валидный ключ в редисе.
    redis.rpoplpush(list, processingList) когда processlingList — пустая строка успешно складывает данные в него.
  2. Имеем 3 сервера с автопереключением через Redis Sentinel. Из-за ошибки из пункта 1 на мастере переполняется память, но не слишком быстро — в итоге до падения по OOM не доходит, но памяти перестает хватать на bgsave. Мастер перестает обрабатывать запросы, т.к. отвалились слейвы и он не может сделать bgsave. Слейвы отваливаются, т.к. мастер не может сделать bgsave, но при этом считают его живым и не осуществляют переключение на себя.
    Единственный выход — вручную убить мастер, предварительно добавив памяти слейвам и исправив ошибку из п.1, чтобы все не началось заново.