为什么在关系上的联接在控制台中执行多个查询

时间:2019-04-07 03:27:49

标签: ruby-on-rails activerecord

我有3张桌子:biographies, affiliations, communities

从属关系属于传记和社区,即从属关系具有传记ID和社区ID作为外键,所有关系都具有has_one关系。传记通过隶属关系与社区联系起来

在Rails控制台中,当我执行以下操作:

b = Biography.joins(:affiliation => :community)

然后,这是sql输出:

 Biography Load (0.2ms)  SELECT  "biographies".* FROM "biographies" INNER JOIN "affiliations" ON "affiliations"."biography_id" = "biographies"."id" INNER JOIN "communities" ON "communities"."id" = "affiliations"."community_id" LIMIT ?  [["LIMIT", 11]]

到目前为止,在相同的控制台会话中继续进行,然后执行:

b.first.affiliation

然后,输出为:

D, [2019-04-06T23:21:20.417201 #38967] DEBUG -- :   Biography Load (0.3ms)  SELECT  "biographies".* FROM "biographies" INNER JOIN "affiliations" ON "affiliations"."biography_id" = "biographies"."id" INNER JOIN "communities" ON "communities"."id" = "affiliations"."community_id" ORDER BY "biographies"."id" ASC LIMIT ?  [["LIMIT", 1]]

D, [2019-04-06T23:21:20.418180 #38967] DEBUG -- :   Affiliation Load (0.1ms)  SELECT  "affiliations".* FROM "affiliations" WHERE "affiliations"."biography_id" = ? LIMIT ?  [["biography_id", 1], ["LIMIT", 1]]

首先:为什么要进行另一个联接,它不应该使用第一个activerecord查询中的联接吗?

秒:为什么还有另一个选择日志?它不应该使用联接的结果而不是新的选择吗?

在执行时继续:

b.first.affiliation.community

然后,它最终输出另一个从社区中进行选择的日志。

它实际上是在运行一个全新的查询,还是仅从第一个查询存储在内存中的结果中获取它?以及我该如何告诉真实与记忆?

谢谢。

2 个答案:

答案 0 :(得分:1)

第一个查询中的join是一个内部联接:它告诉ActiveRecord仅加载与社区有联系的传记。

如果要访问这些记录并避免进行N + 1查询,则可以使用附加的includes语句或使用eager_load

是的:只要您看到控制台输出一条SQL语句,就意味着正在运行一个新查询。

答案 1 :(得分:0)

b = Biography.joins(:affiliation => :community)表示获取由Biographies组成的affiliation的所有community,这意味着您正在基于Biographies加载inner join的子集条件(父表在关联表中至少应有一个引用)。

如果要preload整个结果,可以使用:

b = Biography.preload(:affiliation => :community)