Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在ActiveRecord中预加载完整的深层关系集_Ruby On Rails_Ruby On Rails 3_Performance_Activerecord - Fatal编程技术网

Ruby on rails 在ActiveRecord中预加载完整的深层关系集

Ruby on rails 在ActiveRecord中预加载完整的深层关系集,ruby-on-rails,ruby-on-rails-3,performance,activerecord,Ruby On Rails,Ruby On Rails 3,Performance,Activerecord,从开始,我有一个情况,在我的Rails 3应用程序中,我有一个对象的继承权,这个继承权可能有八个关系,主要是通过有很多和属于关系,因此例如:一个项目有很多用户,用户有很多权限,项目有多个节点,节点属于权限,节点有多个属性,属性有多个编辑历史等等。这都是相当标准的东西,但也有相当数量的。这是一个已经在生产中的应用程序,所以体系结构是我目前所关注的 我遇到的问题是,有时(例如,当我们打开一个项目时)我想加载几乎所有的东西,而有时我不想。因此,我不希望在默认情况下加载所有内容。当我真的想要所有东西时,

从开始,我有一个情况,在我的Rails 3应用程序中,我有一个对象的继承权,这个继承权可能有八个关系,主要是通过
有很多
属于
关系,因此例如:一个
项目有很多用户
用户有很多权限
项目有多个节点
节点属于权限
节点有多个属性
属性有多个编辑历史
等等。这都是相当标准的东西,但也有相当数量的。这是一个已经在生产中的应用程序,所以体系结构是我目前所关注的

我遇到的问题是,有时(例如,当我们打开一个项目时)我想加载几乎所有的东西,而有时我不想。因此,我不希望在默认情况下加载所有内容。当我真的想要所有东西时,尽管有一系列的预加载,但我遇到了一些严重的N+1问题,以至于加载一个页面会产生数百个查询,在某些情况下请求只是超时。在我的关系中,Using没有显示任何明显缺少的
include
语句,但当我查看正在生成的SQL时,我注意到一件事是一些巨大的“IN”查询,上面有数百个ID——尽管它们使用的是主键,但这似乎是一种笨拙的数据检索方法

如果我是从头开始写这样的东西,我可能会编写一个复杂的SQL语句,一次提取所有数据(基于一些我知道但ActiveRecord可能不知道的事情),然后匹配关系。显然,这将打破整个数据库不可知论,但现在页面超时将大大减少用户的麻烦,即使他们确实关心Rails应用程序的纯度,而他们并不关心。我的问题是:


在ActiveRecord或gem中有没有这样的方法可以提供帮助?有没有其他方法可以最大限度地减少执行的查询数量,或者有没有其他技巧可以及时将这些分层数据恢复过来?

如果只使用:includes,rails将选择一种include策略,而这并不是您想要的。这可能会导致急切地加载您实际上不需要的东西。通过id加载相关记录只是它选择的一个选项。有时这比加入要好,有时不是,有时它包含了你不想要的东西

请参阅#急切加载策略

这里没有gem可以提供帮助,因为这是一个非常特定于用例的问题。 Plz发布另一个问题,有一个特定的问题,描述页面上应该显示什么样的确切数据,以及您的模型如何。请提供一些伪代码,显示活动记录数据的消耗情况,从而产生n+1查询

此外,我可以说rails在处理大型数据集方面非常糟糕。如果没有这个选项,也许您应该只显示较少的条目,或者甚至使用自定义sql查询

编辑1: 示例解决您关于可选的即时加载的问题

#class Project

#scope
def self.with_full_users
  includes(:users => {:permisions => :nodes})
end

谢谢我知道它会加载很多我在某些情况下不需要的东西-这就是为什么我说我不想在默认情况下自动包含所有东西-我想知道是否有一些聪明的技巧可以在这里提供帮助-也许是一种作用域调用作用域关系的方法,但听起来好像没有。我不认为想要在深层关系中加载一堆数据是我的情况所特有的,但将模型简化到足以解决SO问题的程度的困难在于问题源于复杂性:(当然,默认情况下,有一些选项可以不急于加载所有内容。最简单的方法是定义一个cusom范围,调用正确的includes。您还可以定义一个与另一个名称的新关系,例如,
has_many:includes_users
,然后将其混淆为急于加载并提供用户类名,因为它现在不会遵循rails的默认值。)s