Open
Conversation
spajic
approved these changes
Apr 14, 2019
| gem 'dotenv-rails' | ||
| gem 'newrelic_rpm' | ||
| gem 'oj' | ||
| gem 'pghero' |
| gem 'newrelic_rpm' | ||
| gem 'oj' | ||
| gem 'pghero' | ||
| gem 'strong_migrations' |
| @@ -0,0 +1,80 @@ | |||
| require 'oj' | |||
|
|
|||
| class DbImporter | |||
| def change | ||
| add_index :buses_services, [:bus_id, :service_id], unique: true, algorithm: :concurrently | ||
|
|
||
| add_foreign_key :trips, :buses |
| disable_ddl_transaction! | ||
|
|
||
| def change | ||
| add_index :buses_services, [:bus_id, :service_id], unique: true, algorithm: :concurrently |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1 Импорт данных
Цель
Оптимизировать механизм перезагрузки расписания из файла так, чтобы он обрабатывал файл
large.jsonв пределах минуты.Процесс
Механизм импорта реализован в виде rake-задачи, причем вся логика находится непосредственно внутри самой задачи. Кажется разумной практикой держать rake-задачи максимально примитивными, а логику уносить в сервисы, которые легко покрыть тестами. Поэтому на первом шаге перенесла весь код "как есть" в сервис
DbImporter.Для сервиса
DbImporterдобавила тесты, которые проверяют полноту и корректность загрузки записей в БД.Для получения обратной связи об эффекте оптимизации добавила ещё одну rake-задачу, которая замеряет время выполнения задачи импорта. Запускаю её на небольшом файле
small.jsonОптимизации
activercord-import). Инстансы моделей я аккумулирую в хэшах. Это позволяет быстро обращаться к нужному инстансу по ключу, а также избегать дублирования записей. В итоге весь импорт делается за четыре вставки.:synchronize: она позволяет иметь в наших промежуточных хэшах ужеpersistedзаписи после выполнения импорта.Ojgem.Результат
2 Отображение расписаний
Цель
Оптимизировать страницы расписаний, т.к. они формируются неэффективно и при росте объёмов начинают сильно тормозить.
Процесс
concurrency10). Замеры делала на базе, которая была импортирована из файлаsmall.json, чтобы иметь быструю ОС.Оптимизации
Самым затратным по времени оказался рендеринг страницы, это хорошо видно по графику:
Во-первых, убрала излишнее дробление на partial'ы, т.к. оно не имеет никакой ценности, но при этом замедляет генерацию документа.
Во-вторых, заменила рендеринг partial'ов в цикле на рендеринг коллекции.
Избавление от N + 1.
Проблема хорошо видна и в отчете newrelic, и невооруженным глазом в консоли: для каждого маршрута из вьюхи мы запрашиваем ассоциации
busиservices.Используем
eager_loadи достаем все связанные записи одним запросом.Теперь, когда для каждого маршрута мы делаем один запрос, но более сложный, включающий объединение таблиц, имеет смысл обратить внимание на индексы. Ниже сравнение планов до и после добавления индексов (добавила на внешние ключи и на поле
start_timeу маршрутов):Результаты
Вот так выглядит график для эндпоинта после всех проведенных оптимизаций:
Результаты выполнения
ab -c 10 -n 100 http://localhost:3000/автобусы/Самара/Москва(до/после) на базе, импортированной изsmall.json:Для базы, импортированной из файла
large.json, эндпоинт отвечает в среднем за310 ms