-
Notifications
You must be signed in to change notification settings - Fork 114
Оптимизация загрузки данных в бд из json и загрузки страницы #117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| described_class.call(Rails.root.join("fixtures/example.json")) | ||
| end.to change(City, :count).by(2).and change(Service, :count).by(2).and change(Bus, :count).by(1).and change(Trip, :count).by(10) | ||
|
|
||
| expect(Bus.last.services.count).to eq(2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Базовый тест, можно бы разбить, но для наших целей хватит))
Также не помешал бы тест на производительность.
|
|
||
| Решила рискнуть и попробовать на `1M.json`, получилось за 30 секунд. Как так? Все записи на месте в бд. | ||
|
|
||
| ## Б. Отображение расписаний |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не помешало бы реквест-тест добавить, моя недоработка )
Хоть и изменения минимальные в этом пункте.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
в ПР видел ещё тесты на view, вот это крутотень конечно
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ну реквест- типа интеграционные, покроют и вью (в той мере, в к-й напишем :)
| t.index ["name"], name: "index_services_on_name", unique: true | ||
| end | ||
|
|
||
| create_table "trips", force: :cascade do |t| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вообще думаю, что индексы на to_id и тд связи не помешали бы ))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Но почему то нигде не показало что поиск по Trip какой то медленный запрос, я поэтому и не стал ничего добавлять. Надо следовать мантре)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Согласна. В реальном приложении важна ещё согласованность данных, это, конечно про foreign key, но индекс обычно сразу тоже.
Сейчас попробовала для интереса добавить внешние ключи и индексы. Конечно, вставка стала намного медленнее - ведь субд индексы ещё поддерживать нужно в актуальном состоянии.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А отображение страницы с индексами - первый запрос так же +-, последующие в 2 раза быстрее где-то.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Т.е. как всегда - решение зависит от целей :)
| @from = City.find_by_name!(params[:from]) | ||
| @to = City.find_by_name!(params[:to]) | ||
| @trips = Trip.where(from: @from, to: @to).order(:start_time) | ||
| @trips = Trip.where(from: @from, to: @to).includes(bus: :services).order(:start_time) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💪
Любопытно только, почему ты добавила его после where?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не специально. Вообще ar соберёт.
| # вот такой insert into buses_services | ||
| # вообще чаще используем has_and_belongs_to_many , потому что часто в связке потом нужны доп. данные и таймстемпы, и свой id | ||
| # тогда можно было бы insert_all использовать | ||
| if buses_services.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ухты, не подумал что так можно было buses_services одним запросом вставить
|
|
||
| Время: 632 | ||
|
|
||
| Решила, что этого хватит. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Аналогичное решение))
araslanov-e
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В)
| end | ||
|
|
||
| def call | ||
| json = JSON.parse(File.read(file)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Можно поробовать разбирать JSON потоков
https://github.com/dgraham/yajl-ffi
https://github.com/dgraham/json-stream
И ваще курутотень будет)
spajic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 ✅
| gem 'rspec-rails' | ||
| gem 'rack-mini-profiler' | ||
| gem 'ruby-prof' | ||
| gem 'strong_migrations' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<3
| @@ -0,0 +1,94 @@ | |||
| class TripsImporter | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
лайк за отдельный класс
| <% end %> | ||
| </ul> | ||
| <%= render "delimiter" %> | ||
| ==================================================== |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
можно оставить паршлы, применить рендеринг коллекций и там даже можно delimiter (spacer) задать параметром https://guides.rubyonrails.org/layouts_and_rendering.html#spacer-templates
так будет не настолько тормозить, и при этом сохраняется удобство декомпозиции на паршлы
| Сначала попробовала поэтапно идти: | ||
|
|
||
| - переписала на один insert trips, не трогая другие части; стало ещё медленнее - откатила пока | ||
| - добавляла уникальные индексы на справочные данные + использовала upsert, но во-первых не так уж сильно оптимизировало, во-вторых оказалось, что `upsert` не возвращает id, если нет вставки. Тест не отловил, т.к. там одна поездка. Дописывать тест не стала (поленилась), но в реальном приложении нужно. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
при вставке какого-то большого объёма данных может иметь смысл наоборот удалить индексы, вставить все данные, а потом уже пересоздать индексы заново
| @from = City.find_by_name!(params[:from]) | ||
| @to = City.find_by_name!(params[:to]) | ||
| @trips = Trip.where(from: @from, to: @to).order(:start_time) | ||
| @trips = Trip.where(from: @from, to: @to).includes(bus: :services).order(:start_time) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
по идее не помешало бы ещё индекс на trips [from_id, to_id], можно составной
именно на время рендеринга это сильно не влияет (так как процент на выполнение этого SQL маленький), но если бы мы заходили со стороны оптимизации БД - там бы это очень помогло;
вынесла код в service object
тест на основную функциональность
оптимизировала вставку в бд
оптмизировала загрузку страницы