Обновить

1.5 миллиона событий в день и ни одной таблицы events: как мы считали продуктовую аналитику 300K-бота по голому проду

Уровень сложностиСложный
Время на прочтение16 мин
Охват и читатели6.1K
Всего голосов 2: ↑2 и ↓0+4
Комментарии2

Комментарии 2

В декартовом произведение, условие m.chat_id IN (SELECT ch.id FROM chats ch WHERE ch.telegram_chat_id = b.telegram_chat_id) внутри JOIN messages m приводит к катастрофическому падению производительности (subquery unnesting failure в MySQL 8 для внешних зависимостей в IN), из-за чего запрос на продакшене с 75 RPS гарантированно уходёт в Lock Wait Timeout или вечный Scan.

Здесь, кажется, стоит разделить две проблемы. Ошибка в расчёте видна из самого SQL: base уже содержит строку на каждое сообщение, а второй JOIN messages повторно присоединяет все сообщения пользователя без привязки к конкретному персонажу. В результате строки размножаются и метрика искажается.

А вот гарантированный subquery unnesting failure и последующий Lock Wait Timeout из текста запроса уже не следуют. MySQL 8 может преобразовать такой IN в semijoin, поэтому без EXPLAIN и информации об индексах нельзя уверенно сказать, какой план был выбран и где именно возникло узкое место.

Сохранился ли план выполнения исходного запроса? Было б интересно сравнить его с исправленной версией.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации