活动记录关系谁需要它?

发布于 2024-12-17 11:44:32 字数 1797 浏览 2 评论 0原文

好吧,我对 Rails 查询感到困惑。例如:

Affiche belongs_to :place
Place has_many :affiches

我们现在可以这样做:

@affiches = Affiche.all( :joins => :place )

或者

@affiches = Affiche.all( :include => :place )

,如果有很多附加信息,我们将得到很多额外的 SELECT:

Place Load (0.2ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 3 LIMIT 1
Place Load (0.3ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 3 LIMIT 1
Place Load (0.8ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 444 LIMIT 1
Place Load (1.0ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 222 LIMIT 1
...and so on...

并且(原文如此!)每个 SELECT:joins > 翻倍了!

从技术上讲,我们云只是这样写:

@affiches = Affiche.all( )

结果完全一样! (因为我们已经声明了关系)。将所有数据保留在一个查询中的方法是删除关系并用“LEFT OUTER JOIN”写一大串,但仍然存在多维数组中数据分组的问题以及类似列名的问题,例如 <代码>id。

做错了什么?或者我做错了什么?

更新:

嗯,我有那个字符串 Place Load (2.5ms) SELECT "places".* FROM "places" WHERE ("places"."id" IN (3,444,222,57,663,32,154,20)) 和一一选择 id 的列表。奇怪的是,但是当我在每个范围内执行此操作时,我会得到这些单独的选择:

 <%= link_to a.place.name, **a.place**( :id => a.place.friendly_id ) %>

标记的 a.place 是产生这些额外查询的位置。

更新 2:

让我做一些数学计算。在控制台中,我们得到:

 Affiche Load (1.8ms)  SELECT affiches.*, places.name FROM "affiches" LEFT OUTER JOIN "places" ON "places"."id" = "affiches"."place_id" ORDER BY affiches.event_date DESC
 <VS>
 Affiche Load (1.2ms)  SELECT "affiches".* FROM "affiches"
 Place Load (2.9ms)  SELECT "places".* FROM "places" WHERE ("places"."id" IN (3,444,222,57,663,32,154,20))

结果:1.8ms 与 4.1ms,差不多,令人困惑......

Well, I`m confused about rails queries. For example:

Affiche belongs_to :place
Place has_many :affiches

We can do this now:

@affiches = Affiche.all( :joins => :place )

or

@affiches = Affiche.all( :include => :place )

and we will get a lot of extra SELECTs, if there are many affiches:

Place Load (0.2ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 3 LIMIT 1
Place Load (0.3ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 3 LIMIT 1
Place Load (0.8ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 444 LIMIT 1
Place Load (1.0ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 222 LIMIT 1
...and so on...

And (sic!) with :joins used every SELECT is doubled!

Technically we cloud just write like this:

@affiches = Affiche.all( )

and the result is totally the same! (Because we have relations declared). The wayout of keeping all data in one query is removing the relations and writing a big string with "LEFT OUTER JOIN", but still there is a problem of grouping data in multy-dimentional array and a problem of similar column names, such as id.

What is done wrong? Or what am I doing wrong?

UPDATE:

Well, i have that string Place Load (2.5ms) SELECT "places".* FROM "places" WHERE ("places"."id" IN (3,444,222,57,663,32,154,20)) and a list of selects one by one id. Strange, but I get these separate selects when I`m doing this in each scope:

 <%= link_to a.place.name, **a.place**( :id => a.place.friendly_id ) %>

the marked a.place is the spot, that produces these extra queries.

UPDATE 2:

And let me do some math. In console we have:

 Affiche Load (1.8ms)  SELECT affiches.*, places.name FROM "affiches" LEFT OUTER JOIN "places" ON "places"."id" = "affiches"."place_id" ORDER BY affiches.event_date DESC
 <VS>
 Affiche Load (1.2ms)  SELECT "affiches".* FROM "affiches"
 Place Load (2.9ms)  SELECT "places".* FROM "places" WHERE ("places"."id" IN (3,444,222,57,663,32,154,20))

Comes out: 1.8ms versus 4.1ms, pretty much, confusing...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

┊风居住的梦幻卍 2024-12-24 11:44:32

这里的事情真的很奇怪,因为 :include 选项旨在从每个 Affiche 收集 place_id 属性,然后使用如下所示的选择查询一次获取所有地点:

select * from places where id in (3, 444, 222)

您可以在导轨控制台。只需启动它并运行该代码片段:

ActiveRecord::Base.logger = Logger.new STDOUT
Affiche.all :include => :place 

您可能会偶然获取附件,但实际上并未在代码中的某个位置包含位置,而是为每个附件调用 place ,从而使 Rails 为每个附件执行单独的查询。

Something is really strange here because :include option is intended to gather place_id attribute from every affiche and then fetch all places at once using select query like this:

select * from places where id in (3, 444, 222)

You can check that in rails console. Just start it and run that snippet:

ActiveRecord::Base.logger = Logger.new STDOUT
Affiche.all :include => :place 

You might be incidentally fetching affiches without actually including places somewhere in your code and than calling place for every affiche making rails to perform separate query for every one of them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文