【发布时间】:2015-02-12 10:29:49
【问题描述】:
我有这些模型:
汽车:
class Car < ActiveRecord::Base
has_many :car_services, dependent: :destroy
has_many :services, through: :car_services
end
汽车服务
class CarService < ActiveRecord::Base
belongs_to :car
belongs_to :service
validates_uniqueness_of :service_id, scope: :car_id
end
卡车
class Truck < ActiveRecord::Base
has_many :truck_services, dependent: :destroy
has_many :services, through: :truck_services
end
卡车服务
class TruckService < ActiveRecord::Base
belongs_to :truck
belongs_to :service
end
服务
class Service < ActiveRecord::Base
has_many :car_services
has_many :cars, through: :car_services
has_many :truck_services
has_many :trucks, through: :truck_services
end
在控制器的动作中(汽车和卡车的动作是分开的)我这样查询模型:
@cars = Car.find_by_sql("SELECT ...")
...
@trucks = Truck.find_by_sql("SELECT ...")
然后在各自的视图中:
<% @cars.each do |result| %>
<li data-services="<% result.services.each do |service| %><%= service.name %>,<% end %>">...</li>
...
<% end %>
这个过程非常适合cars,速度非常快。
trucks 的操作不同,但过程相同:
<% @trucks.each do |result| %>
<li data-services="<% result.services.each do |service| %><%= service.name %>,<% end %>">...</li>
...
<% end %>
现在,这个过程非常缓慢。当我尝试调试原因时(因为正如我所提到的,这两种模型的过程是相同的,但对于汽车来说,它的工作速度非常快,即使在 car 模型中是 600k 记录并且在 truck“仅”300k 中) ,我在控制台日志中发现了以下信息:
...
Service Load (159.1ms) SELECT `services`.* FROM `services` INNER JOIN `truck_services` ON `services`.`id` = `truck_services`.`service_id` WHERE `truck_services`.`truck_id` = 35769
Service Load (166.8ms) SELECT `services`.* FROM `services` INNER JOIN `truck_services` ON `services`.`id` = `truck_services`.`service_id` WHERE `truck_services`.`truck_id` = 45681
Service Load (151.4ms) SELECT `services`.* FROM `services` INNER JOIN `truck_services` ON `services`.`id` = `truck_services`.`service_id` WHERE `truck_services`.`truck_id` = 50974
...
这怎么可能?为什么cars 也没有看到这些行,而truck 却看到了这些行?我错过了什么吗?我在考虑 MySQL 表中缺少索引,但没有使用任何索引。
整个星期六我都在与这个问题作斗争,但我没有解决这个问题...
如果您能提供解决此问题的建议,我将不胜感激。
非常感谢你们。
【问题讨论】:
-
汽车版不会出现这些查询,还是只是更快?
-
汽车和卡车的
SELECT ...(隐藏,但可能与问题最相关的一段代码)是否等效? -
@FrederickCheung 它们不会发生,而且速度更快。
-
@numbers1311407 是的。逻辑是一样的。
-
什么是
shipper_id,为什么在 WHERE 子句中使用它?
标签: ruby-on-rails ruby join activerecord has-many