Conversation
spajic
left a comment
There was a problem hiding this comment.
Very nice work, respect! 🫡
| </head> | ||
|
|
||
| <body> | ||
| <%= link_to "Database Analyzer", pg_hero_path, target: :blank %> |
| BusesService.import buses_services.values | ||
| Trip.import trips | ||
|
|
||
| cities, services, buses, trips = nil |
There was a problem hiding this comment.
странновато (просто лишняя строчка?)
| <% end %> | ||
| </ul> | ||
| <%= render "delimiter" %> | ||
| ==================================================== |
There was a problem hiding this comment.
FYI: есть API для рендеринга коллекций, там можно даже указать шаблон spacer параметром.
https://guides.rubyonrails.org/layouts_and_rendering.html#spacer-templates
Это позволяет находить компромисс между удобством разбиения на partial’ы и не настолько медленно работает как наивный рендеринг в цикле.
|
|
||
| # Install JavaScript dependencies if using Yarn | ||
| # system('bin/yarn') | ||
| system('bin/yarn') |
There was a problem hiding this comment.
у нас тут нет же никакого js
| before { ImportTripsService.call('fixtures/example.json') } | ||
|
|
||
| it 'trips from DB are equal to imported' do | ||
| expect(Trip.all.map(&:to_h).sort_by(&:to_s)).to eq trip_from_file.sort_by(&:to_s) |
| - Метрика изменилась: 1К рейсов - с **16,4 сек** до **7,5 сек**. Самих запросов SELECT стало значительно меньше - < 4000 | ||
|
|
||
| ### Находка №2 - добавление индекса к автобусам | ||
| Дальнейшее изучение pgHero показывает, что 44% тратится на INSERT INTO trips и 23% SELECT from buses. Сами рейсы пока трогать не будем, добавим индекс к автобусам. |
There was a problem hiding this comment.
я бы не стал на самом деле через призму pg_hero анализировать этот таск
там довольно-таки очевидно (как ни посмотри), что делается бешеное кол-во запросов в pg, и надо от этого уйти к какому-то батч-импорту
а pg_hero всё-таки больше заточен на анализ штатно работающего OLTP веб-приложения, а тут у нас такая специфическая и разовая задача импорта
| - Метрика изменилась: 1К рейсов - с **6,9 сек** до **1,5 сек**. Ура! | ||
|
|
||
| ### Попадание в метрику. Выводы. Тесты | ||
| Теперь можно проводить замер и на `large.json` - **55 сек** - как раз укладываемся в метрику! |
| ```log | ||
| Completed 200 OK in 579ms (Views: 475.8ms | ActiveRecord: 81.6ms) | ||
| ``` | ||
| Большая часть времени - загрузка вьюх. И много времени уходит на запрос COUNT (@trips.count). Помним, что это всегда лишний запрос, поэтому меняем на #size. Эффекта нет - запрос COUNT продолжает отправляться. Пробуем #length - помогает. *Интересно, как в современных рельсах работает вопрос о размере* |
|
|
||
| ### Находка 3 - индексы | ||
| Увеличиваем кол-во рейсов до 100к. Наш запрос занимает 600 мс. Из них 530 - вьюха, 48 - AR | ||
| Уже до этого ставили `rack-mini-profiler`, но знакомился с ним поверхностно - обращал внимание только на общее время загрузки страницы. Теперь решил изучить подробнее. Большое положительное удивление доставило количество опций - когда можно открывать отчёт с другими профилировщиками. Когда видишь это на уроке - не проникаешься его мощью. Но когда уже все запросы как родные - `rack-mini-profiler` может заменить почти всё остальное (наверное) |
There was a problem hiding this comment.
да, очень удобно; просто глянул, сразу плюс-минус понятно откуда ноги растут если проект знакомый уже
| Добавляем индекс к | ||
| - cities :names | ||
| - trips [:from_id, :to_id] | ||
| `strong_migrations` предлагает использовать опции `disable_ddl_transaction!`, `algorithm: :concurrently` - окей, мы для этого его и ставили. |
There was a problem hiding this comment.
да, это отличный совет, иначе можно таблицу залочить и сайт свой положить
No description provided.