На работе не давал покоя один метод в сервисе, который работает не самым идеальным способом, делался на коленке, но всё же ускорял систему по сравнению с тем, что было. По сути он 3-4 раза дёргал один муторный #SQL запрос в цикле и это было лучше, чем 3-4 параллельных HTTP-запроса. SQL-запрос был и правда муторным, с кучей логики, поэтому переписывать его год назад не начинал, просто переиспользовал как есть.

Недавно обвешал свой сервис метриками и заметил, что #ORM, курва, порождает сильно (3...4) * (1...3) SQL-запроса, то есть в худшем случае 12. Жопка!

Сел, часа полтора проковырялся с оконными функциями, а потом оказалось, что мне вполне можно было обойтись простым советским SELECT DISTINCT ON. Ещё за полчаса превратил его в ORM (плохому танцору всегда мешает, ага). И вуаля, всё работает в один SQL-запрос.

Ещё за час пересобрал нагрузочное тестирование на яндекс-танком на локалхосте. Вроде и нелепо, зато можно никуда не деплоиться, а умеючи, разграничив всё taskset'ами и позакрывав лишнее - результаты близки к достоверным. Ну и прям большой плюс - изоляция тестируемого/изменяемого участка системы, а то у нас любят пострелять из JMeter на тестовых слоях через VPN и кучу проксей, в сервис, который крутится в оркестровщике, который может то на хорошую ноду закинуть, то на хреновничающую - короч волатильности хватает. Не, инфраструктуру так тестить (особенно всякие мультицоды) - хорошо и правильно, но это другое.

И вскрылось любопытное. Старый код неплохо работает под нагрузкой в 100 #RPS, но дальше деградирует дичайше:

100 RPS: avg 10.8ms, p99: 24ms
150 RPS: avg 400ms, p99: 555ms
300 RPS: avg: 389ms, p99: 1360ms

С запиленной оптимизацией интереснее:

300 RPS: avg 7.1ms, p99: 41ms
350 RPS: avg 161ms, p99: 297ms
400 RPS: avg 153ms, p99: 805ms, 0.29% HTTP/500 из-за таймаута ожидания коннекта из пула соединений.

В понедельник скорее всего без вопросов пройдёт ревью, постреляю ещё в тестовых окружениях нагрузочным, так-то прикольно.

После предыдущей пачки оптимизаций, эта чёрная пятница прошла без каких-либо проблем, в прошлую - нас прям система мониторинга завалила алертами, то коннектов к #БД много, то CPU троттлится, то пятисотим. И это при том, что я ещё и подрезал ресурсы. А в этот раз нагрузка на CPU выше 20% не поднималась.

Надо будет ещё сходить до фронтендеров, поузнавать что из наших ответов мы можем вырезать, сделать им новую API-шку, избавиться от `select x.*, y.*, z.* from` в основном запросе, в теории сокращение ширины вытягиваемой из БД строки + сокращение payload ответов может ещё небольшой буст к задержкам дать. Дальше только на #Rust переписывать, кек.

#Работа #Работушка