Иногда в команде попадаются люди, которые почему-то считают, что если запрос написан плохо, но работал хорошо, то когда он начинает работать плохо - это проблема администраторов, которые что-то не так сделали с базой, или не сделали, а должны были. Сталкиваюсь с этим достаточно часто, чтобы не дублировать, решил записать и распространять ссылкой.
Логика непостижима. Вот есть у тебя запрос с вложенными циклами (заметьте, есть конкретная команда программистов во главе с тимлидом, которая считает это хорошим запросом, но это уже другая тема)
Я не считал, но в том запросе, о кусок плана которого я привел на картинке, говорят, было 35 вложенных циклов.
Количество итераций вложенных запросов считается степенью. Ну, то есть если 35 вложенных циклов по 5 итераций - это 5^35 (предлагаю посчитать это и офигеть от длины числа). Только неосиливший математику начальной школы человек не понимает кардинальность разницы между 5^35 и 10^35, хотя, казалось бы, 5 и 10 - смешная разница даже для подсчета на пальцах. Понимаете, неустойчивость работы такой конструкции? Чуть добавили где-то на каком-то уровне и вот вся эта лопата, которая работала секунды, начинает работать сутками. И это не только в отношении вложенных циклов действует, хотя на них это самое падение производительности в зависимости от объема данных проявляется наиболее очевидно. С первого раза обращайте внимание не только на Cost, но и на CPU cost плана запроса.
Еще из разницы, которая может поставить на колени сервер, надо отметить работу с памятью. Какая-нибудь неудачная сортировка, with с быстрорастущим набором данных и вот, запрос который еще вчера работал в памяти, вываливается на диск и начинает работать кратно медленнее, начинает тормозить сам, мешать другим запросам, а если этот запрос еще предусмотрен от нескольких пользователей одновременно, то ситуация может быть фатальной для базы.
Что еще часто встречается - программисты начинают накапливать техдолг, в угоду собственной лени или неудачной постановки целей команды они пишут новое и не исправляют то, что не приносит деньги напрямую. В итоге тут запросик плохой, там не очень, ком "говнокода" копится, копится и тут выясняется, что даже то, что работало хорошо, начинает работать плохо просто потому, что ресурсы поедаются другими весьма неоптимальными запросами. Где-то перестает хватать памяти, где-то вымывается кеш, где-то перестает хватать ресурсов процессора... Причем, сначала это может быть вообще незаметно, но потом со стремительностью удара Тайсона ситуация меняется, поскольку заброшенных запросов много, они идут валом, непонятно, что именно является самым критическим, потому, что валяется вообще все. Плач, ругань, конфликты, стоны раненых и уязвленных в самолюбии, жертвы стресса...
Да, достаточно часто удается выделить какой-то отдельный запрос, исправление которого дает возможность вывести базу из штопора. И тут в полный рост встает причина, по которой запрос не был переписан ранее. Во-первых, вполне возможно, что команда состоит из программистов, которые хорошо пишут, например, на плюсах, но вообще не догадываются о том, как надо писать правильные SQL-запросы. Патовая ситуация. Исправить надо
быстро, много и со знанием, а вообще некому. То есть, даже если аварийно привлечь человека со стороны, ему еще надо будет погрузиться в это все, чтобы понять, в какую сторону метаться, а это, вполне возможно, полный простой бизнеса и репутационные потери. Во-вторых, вполне возможно, что написать нормальный запрос в принципе невозможно, потому, что данные лежат по разным углам и, например, половина из них - расчетная. То есть архитектора решения нет, все собиралось в эту таблицу... потому, что просто исторически так сложилось. Но тот, кто начинал, хотел сделать быстро и думал, что в табличке будет 1000 строк, а тот, кто пишет запросы сейчас, охреневает от того, что в ней уже несколько миллиардов строк и любой запрос, какой бы он ни писал, работает несколько минут вместо секунды, как раньше. Опять патовая ситуация. Вроде бы все было, как вчера, но вчера работало, а сегодня уже нет. И чтобы поправить, нужно неделю только перемещать данные в какой-то более пригодный вид, и непонятно сколько времени нужно, чтобы понять, как и куда их перемещать, чтобы не сломалось все остальное.
Ну, а требующим, чтобы база работала, как вчера, можете предложить восстановить вчерашний бекап и не менять данные. Это будет "как вчера".
P.S. Да, забыл ответить на вопрос в заголовке. Ответ очень простой - "никак". Плохой запрос должен быть переписан. Все остальное - разговоры в пользу бедных. В лучшем случае ценой времени и нервов администратора базы данных можно временно поправить что-то.