加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – ActiveRecord使用连接来提高性能,但是将所有相

发布时间:2020-12-17 03:32:42 所属栏目:百科 来源:网络整理
导读:除非我弄错了:连接具有比包含更好的性能,因为在数据库级别: 连接会导致内部连接 includes会导致子查询 通常,内连接比子查询更快. 例: #app/models/owner.rbclass Owner ActiveRecord::Base has_many :petsend #app/models/pet.rbclass Pet ActiveRecord::
除非我弄错了:连接具有比包含更好的性能,因为在数据库级别:

>连接会导致内部连接
> includes会导致子查询

通常,内连接比子查询更快.

例:

#app/models/owner.rb
class Owner < ActiveRecord::Base
  has_many :pets
end 

#app/models/pet.rb
class Pet < ActiveRecord::Base
  belongs_to :owner
end

使用rails控制台:

# showing how 'includes' in rails causes an IN statement which is a subquery 
irb(main):001:0> @owners = Owner.all.includes(:pets)
Owner Load (2.7ms)  SELECT "owners".* FROM "owners"
Pet Load (0.4ms)  SELECT "pets".* FROM "pets" WHERE "pets"."owner_id" IN (1,2,3)

现在使用连接导致内部连接:

irb(main):001:0> @owners = Owner.all.joins(:pets)
Owner Load (0.3ms)  SELECT "owners".* FROM "owners" INNER JOIN "pets" ON "pets"."owner_id" = "owners"."id"

所以看起来似乎总是更好的使用连接包括因为:

> include导致子查询(IN语句)
> join会导致内部联接,通常比子查询更快

但是,使用连接有一个问题. This article does a great job describing it.基本上,include将所有关联的对象加载到内存中,这样,如果查询这些关联对象的任何属性,它就不会命中数据库.同时,连接不会将相关对象的属性加载到内存中,因此如果查询任何属性,它会对数据库进行额外的命中.

所以这是我的问题:是否可以像连接一样进行内部连接以提高性能,但同时将所有关联的对象加载到内存中,就像包含那样?
换句话说:是否有可能将所有关联的对象加载到内存中,如include,但是导致内部连接而不是子查询?

解决方法

我认为你假设JOIN总是比两个查询更快是不正确的.它在很大程度上取决于数据库表的大小.

想象一下,您的数据库中有成千上万的拥有者和宠物.然后,即使您只想加载10条记录,您的数据库也必须首先加入所有数据库.另一方面,一个查询加载10个所有者和一个查询来加载该10个所有者的所有宠物将比JOIN快.

我认为两种方法都可以解决不同的问题:

当需要组合两个表以对两个表的数据运行查询时,将使用>连接.
> includes用于避免N 1个查询.

顺便说一句:Rails documentation有一个注释,包括对连接的性能优势:

This will often result in a performance improvement over a simple join.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读