Успеть за десять минут
Десять минут... Такую планку я сам себе установил для ожидания выполнения запросов в MySQL. Если запрос не выполнялся за это время, наступала стадия принятия своей ошибки, и мне приходилось что-то менять.
Я только освоил базовый синтаксис sql, смог построить не самые сложные запросы, и вот я уже работаю с новым проектом.
Я тогда ещё вообще не знал, что такое индексы. На интуитивном уровне понимал, что говорит EXPLAIN. И самые сложные запросы до этого момента выполнялись в районе двух минут. Настало время новых вызовов.
Это была аналитика рекрутинга. Была таблица кандидатов и отдельная таблица событий по ним. В событиях хранилась история того, что происходило с кандидатом: переходы между статусами, собеседования и другие действия. Естественно, таблица событий была намного больше таблицы кандидатов. И также очевидно, что для расчёта часто требовалась информация и о том, и о другом.
Ты честно пишешь SQL, соединяешь две таблицы и ждёшь... В MySQL можно ждать минуту, две, пять... Но вот проходит десять, а запрос всё ещё выполняется.
Хороший кейс для обучения, подумал я, и решил разбираться в проблеме вместе с нейронкой, давая ей вывод EXPLAIN. Меняю одно, другое, а результат всё тот же. При этом то, что не понимаю, пока стараюсь не использовать.
И вот тут я решил, что пора взять лист бумаги и разобраться, а что я вообще делаю, с какими таблицами работаю, почему подобные операции раньше не приводили к таким проблемам.
В запросе было много джойнов, но важно следующее. Есть большая таблица событий и есть маленькая таблица кандидатов. Я подумал: а я вообще правильно их соединяю? Индексы, конечно, хорошо. Но может, имеет значение, большую таблицу я сначала клею к маленькой или маленькую к большой?
В несколько итераций мне удаётся найти проблемное соединение, и я решаю просто поменять порядок JOIN. Начинаем с большой, клеим к ней маленькую. Мою догадку подтверждает мой нейроучитель. Так, якобы, должно быть быстрее. Запускаем код, не добавляя индексы и не изменив больше ни одного символа. Вуаля!
Запрос, который выполнялся больше 10 минут, стал выполняться примерно за минуту.*
Это был тот самый случай, который стал триггером к изучению того, что вообще происходит внутри базы: что показывает EXPLAIN, зачем нужны индексы, почему порядок и способ соединения таблиц может иметь значение и чем вообще отличается база, с которой работает приложение, от базы, в которой ты гоняешь тяжёлую аналитику (OLTP и OLAP)
Сейчас всё это кажется базовым минимумом. А тогда я впервые очень наглядно понял простую вещь: я умею писать SQL, но практически ничего не знаю о том, как он выполняется. В моей памяти это важная точка для дальнейшего развития.
*вообще говоря, результат может не повториться, так как оптимизатор БД может выбрать другой план исполнения