Skip to content

Commit c315cda

Browse files
committed
chore: 3rd & 4th steps case b
1 parent 028cd9e commit c315cda

9 files changed

+42
-13
lines changed

app/controllers/trips_controller.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ class TripsController < ApplicationController
22
def index
33
@from = City.find_by_name!(params[:from])
44
@to = City.find_by_name!(params[:to])
5-
@trips = Trip.where(from: @from, to: @to).preload(bus: :services).order(:start_time)
5+
@services = Service.pluck(:id, :name).to_h
6+
@trips = Trip.where(from: @from, to: @to).preload(bus: :bus_services).order(:start_time)
67
end
78
end

app/models/bus.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class Bus < ApplicationRecord
2121
].freeze
2222

2323
has_many :trips
24-
has_and_belongs_to_many :services, join_table: :buses_services
24+
has_many :bus_services, class_name: 'BusService'
25+
has_many :services, through: :bus_services
2526

2627
validates :number, presence: true, uniqueness: true
2728
validates :model, inclusion: { in: MODELS }

app/models/bus_service.rb

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# == Schema Information
2+
#
3+
# Table name: buses_services
4+
#
5+
# id :bigint not null, primary key
6+
# bus_id :integer
7+
# service_id :integer
8+
#
9+
class BusService < ApplicationRecord
10+
self.table_name = :buses_services
11+
12+
belongs_to :bus
13+
belongs_to :service
14+
end

app/models/service.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ class Service < ApplicationRecord
1919
'Можно не печатать билет',
2020
].freeze
2121

22-
has_and_belongs_to_many :buses, join_table: :buses_services
22+
has_many :service_buses
23+
has_many :buses, through: :service_buses
2324

2425
validates :name, presence: true
2526
validates :name, inclusion: { in: SERVICES }

app/views/trips/_service.html.erb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<li><%= "#{service.name}" %></li>
1+
<li><%= "#{@services[bus_service.service_id]}" %></li>

app/views/trips/_services.html.erb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<li>Сервисы в автобусе:</li>
22
<ul>
3-
<%= render partial: "service", collection: services %>
3+
<%= render partial: "service", collection: bus_services, as: :bus_service %>
44
</ul>

app/views/trips/_trip.html.erb

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<li><%= "В пути: #{trip.duration_minutes / 60}ч. #{trip.duration_minutes % 60}мин." %></li>
55
<li><%= "Цена: #{trip.price_cents / 100}р. #{trip.price_cents % 100}коп." %></li>
66
<li><%= "Автобус: #{trip.bus.model}#{trip.bus.number}" %></li>
7-
<% if trip.bus.services.present? %>
8-
<%= render "services", services: trip.bus.services %>
7+
<% if trip.bus.bus_services.present? %>
8+
<%= render "services", bus_services: trip.bus.bus_services %>
99
<% end %>
1010
</ul>
1111

app/views/trips/index.html.erb

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<%= "Автобусы #{@from.name}#{@to.name}" %>
33
</h1>
44
<h2>
5-
<%= "В расписании #{@trips.count} рейсов" %>
5+
<%= "В расписании #{@trips.length} рейсов" %>
66
</h2>
77

88
<%= render partial: "trip", collection: @trips, spacer_template: 'delimiter' %>
99

10-
<% if @trips.size > 0 %>
10+
<% if @trips.length > 0 %>
1111
<%= render "delimiter" %>
1212
<% end %>

case-study-b.md

+16-4
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,26 @@
3434
- количество sql запросов для `trips/index.html.erb` сократилось до 12
3535

3636
### Ваша находка 2
37-
- rack mini profiler (и логи веб сервера) показал, что основное время тратится на рендеринг шаблонов (`trips/index.html.erb 2091.1
38-
4917.9`).
37+
- rack mini profiler (и логи веб сервера) показал, что основное время тратится на рендеринг шаблонов `trips/index.html.erb 2091.1
38+
4917.9`.
3939
- рендереринг всех коллекций через `render partial:`
4040
- метрика снизилась до 1 секунды
4141
- `Rendering: trips/index.html.erb 716.2 975.7`
4242

43-
### Ваша находка №2
44-
- rack mini profiler показал, что дольше всего (412.1 ms) выполняется запрос `SELECT "buses_services".* FROM "buses_services" WHERE "buses_services"."bus_id" IN ($1, <...>`. делаю explain, он показывает `Seq Scan on buses_services` как основную точку роста.
43+
### Ваша находка 3
44+
- rack mini profiler показал, что основное время занимает запрос в сервисы (около 400мс).
45+
- вместо habtm делаю промежуточную таблицу, для нее и делаю eager loading вмсто services. в контроллере достаю весь и собираю хэш-справочник (id=>name) сервисов и использую его во вью.
46+
- метрика особенно не снизилась
47+
- запрос пропал из логов профилировщика (вместо него показывается запрос в сервисы, около 25мс, что 8 раз меньше)
48+
49+
### Ваша находка 4
50+
- rack mini profiler показал, что производится и запрос по count, и идентичный по выборке данных.
51+
- меняю count на length.
52+
- метрика особенно не снизилась
53+
- запрос count пропал из логов профилировщика
54+
55+
### Ваша находка № 5
56+
- rack mini profiler показал, что долго выполняются запросы `SELECT "buses_services".* FROM "buses_services" WHERE "buses_services"."bus_id" IN ($1, <...>` (делаю explain, он показывает `Seq Scan on buses_services` как основную точку роста),``
4557
- Добавляю индекс на `bus_id`
4658
- как изменилась метрика
4759
- как изменился отчёт профилировщика - исправленная проблема перестала быть главной точкой роста?

0 commit comments

Comments
 (0)