如果我急于加载关联的子记录,那么这意味着未来的 WHERE 检索将不会再次挖掘数据库?
If I eager load associated child records, then that means future WHERE retrievals won't dig through database again?
只是想了解...如果在某些方法开始时我急于加载记录及其关联的子项,如下所示:
@object = Object.include(:children).where(email:"test@example.com").first
那么这是否意味着如果以后我必须查看该对象的子对象,这将不会生成更多的数据库查询?
即
@found_child = @object.children.where(type_of_child:"this type").first
不幸的是不能 - 使用 ActiveRecord::Relation 方法如 where
将再次查询数据库。
但是,您可以使用标准的 Array / Enumerable 方法过滤数据而无需任何进一步查询:
@object.children.detect {|child| child.type_of_child == "this type"}
它将针对您的情况生成另一个数据库查询。
预加载用于避免 N+1 查询。这是通过加载所有关联对象来完成的。但是,当您想稍后使用 where
过滤该列表时,这将不起作用,Rails 将构建一个新查询和 运行 那个。
就是说:在您的示例中,include
实际上会使您的代码变慢,因为它加载关联对象,但无法使用它们。
我会将您的示例更改为:
@object = Object.find_by(email: "test@example.com")
@found_child = @object.children.find_by(type_of_child: "this type")
只是想了解...如果在某些方法开始时我急于加载记录及其关联的子项,如下所示:
@object = Object.include(:children).where(email:"test@example.com").first
那么这是否意味着如果以后我必须查看该对象的子对象,这将不会生成更多的数据库查询?
即
@found_child = @object.children.where(type_of_child:"this type").first
不幸的是不能 - 使用 ActiveRecord::Relation 方法如 where
将再次查询数据库。
但是,您可以使用标准的 Array / Enumerable 方法过滤数据而无需任何进一步查询:
@object.children.detect {|child| child.type_of_child == "this type"}
它将针对您的情况生成另一个数据库查询。
预加载用于避免 N+1 查询。这是通过加载所有关联对象来完成的。但是,当您想稍后使用 where
过滤该列表时,这将不起作用,Rails 将构建一个新查询和 运行 那个。
就是说:在您的示例中,include
实际上会使您的代码变慢,因为它加载关联对象,但无法使用它们。
我会将您的示例更改为:
@object = Object.find_by(email: "test@example.com")
@found_child = @object.children.find_by(type_of_child: "this type")