在 Rails 5 中优化数据库查询
Optimizing database query in Rails 5
我有4个模型
module Vehicle
has_many :routes
end
module Route
has_many :route_users
belongs_to :vehicle
end
module RouteUser
belongs_to :route
belongs_to :user
end
module User
belongs_to :route_user
end
我的目标是return最近driver(一个user
)通过aggregate.rb
;具体来说,我需要用户 id, first_name, last_name
.
attributes = {
id: vehicle.id,
... other attributes ...
}
attributes.merge!(
driver: {
id: vehicle.routes.last.route_users.last.user.id,
first_name: vehicle.routes.last.route_users.last.user.first_name,
last_name: vehicle.routes.last.route_users.last.user.last_name
}
) if vehicle.routes.present? && vehicle.routes.last.route_users.present?
如您所见,.merge!
加载了一堆信息并显着降低了 aggregate.rb
return 的速度。有没有办法优化这个 return 使其更快?我错过了什么吗?
您可以改进您的用户模型以简化查询。
class User < ApplicationRecord
has_many :route_users
has_many :routes, through: :route_users
has_many :vehicles, through: :routes
end
当一侧的查询很大时,最好的方法是两次反转逻辑,从用户进行查询,例如:
先取last_user_drive,然后用他的字段合并成属性
last_user_driver = User.joins(routes: :vehicle).where(vehicle: {id: vehicle.id}).order('routes.created_at').last
...
attributes.merge!(
driver: {
id: last_user_driver.id,
first_name: last_user_driver.first_name,
last_name: last_user_driver.last_name
}
) if last_user_driver.present?
我有4个模型
module Vehicle
has_many :routes
end
module Route
has_many :route_users
belongs_to :vehicle
end
module RouteUser
belongs_to :route
belongs_to :user
end
module User
belongs_to :route_user
end
我的目标是return最近driver(一个user
)通过aggregate.rb
;具体来说,我需要用户 id, first_name, last_name
.
attributes = {
id: vehicle.id,
... other attributes ...
}
attributes.merge!(
driver: {
id: vehicle.routes.last.route_users.last.user.id,
first_name: vehicle.routes.last.route_users.last.user.first_name,
last_name: vehicle.routes.last.route_users.last.user.last_name
}
) if vehicle.routes.present? && vehicle.routes.last.route_users.present?
如您所见,.merge!
加载了一堆信息并显着降低了 aggregate.rb
return 的速度。有没有办法优化这个 return 使其更快?我错过了什么吗?
您可以改进您的用户模型以简化查询。
class User < ApplicationRecord
has_many :route_users
has_many :routes, through: :route_users
has_many :vehicles, through: :routes
end
当一侧的查询很大时,最好的方法是两次反转逻辑,从用户进行查询,例如:
先取last_user_drive,然后用他的字段合并成属性
last_user_driver = User.joins(routes: :vehicle).where(vehicle: {id: vehicle.id}).order('routes.created_at').last
...
attributes.merge!(
driver: {
id: last_user_driver.id,
first_name: last_user_driver.first_name,
last_name: last_user_driver.last_name
}
) if last_user_driver.present?