Rails 预加载问题 Find(:all, :include => [:model])

发布于 2024-08-19 19:01:39 字数 651 浏览 9 评论 0原文

我有一个主题和一个项目模型。我在他们之间有一个多对多的屁股(HABTM)。

在主题的索引页中,我想显示每个主题拥有的项目数量。所以我的控制器里有

@topics = Topic.all(:include => [:projects])

,到目前为止一切都很好。问题是项目模型太大,查询仍然很慢

Topic Load (1.5ms)   SELECT * FROM "topics" 

Project Load (109.2ms)   SELECT "projects".*, t0.topic_id as the_parent_record_id FROM "projects" INNER JOIN "projects_topics" t0 ON "projects".id = t0.project_id WHERE (t0.topic_id IN (1,2,3,4,5,6,7,8,9,10,11)) 

有没有办法让第二个查询不选择*而只选择名称或ID?因为HABTM Ass不支持counter_cache,而且我真的不想自己实现它......那么有没有办法让第二个查询更快?

我只需要拉动计数而不加载整个项目对象...

提前致谢,

Nicolás Hock Isaza

I have a Topic and a Project model. I have a Many-to-many ass between them (HABTM one).

In the Topic's Index Page, I want to display the number of projects that each topic have. So I have

@topics = Topic.all(:include => [:projects])

In my controller, and so far so good. The problem is that the Project Model is so big that the query is still really slow

Topic Load (1.5ms)   SELECT * FROM "topics" 

Project Load (109.2ms)   SELECT "projects".*, t0.topic_id as the_parent_record_id FROM "projects" INNER JOIN "projects_topics" t0 ON "projects".id = t0.project_id WHERE (t0.topic_id IN (1,2,3,4,5,6,7,8,9,10,11)) 

Is there a way to make the second query not to select * but just the name or the ID? Because the counter_cache is not supported by the HABTM Ass, and I don't really want to implement it by myself... so is there a way to make this second query faster?

I just need to pull the count without loading the whole project object...

Thanks in advance,

Nicolás Hock Isaza

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

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

发布评论

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

评论(2

旧瑾黎汐 2024-08-26 19:01:39
  1. counter_cache 非常容易实现,
  2. 您可以将 habtm 转换为双 has_many,即 has_many :projects_topics 在项目和主题模型中(以及在projects_topics中属于_to),然后使用 counter_cache 或仅在projects_topics上进行急切加载,
  3. 您可以执行以下操作:select => "count(projects_topics.id)", :group =>; “topics.id”,但是如果你关心的话,这不适用于 postgresql...

第二个选项是最好的 IMO,我通常根本不使用 habtm,只使用 double has_many :)

  1. counter_cache is very easy to implement
  2. you can convert habtm to double has_many, i.e. has_many :projects_topics in both project and topic model (and belongs_to in projects_topics) and then use counter_cache or do eager loading only on projects_topics
  3. you can do :select => "count(projects_topics.id)", :group => "topics.id" but this won't work well with postgresql if you care about it...

The second option is the best IMO, I usually don't use habtm at all, only double has_many :)

○闲身 2024-08-26 19:01:39

要扩展 Devenv 的答案 计数器缓存 是您通常使用的这种场景。

来自 API 文档:

缓存所属对象的数量
通过使用关联类
的increment_counter和
减量计数器。计数器缓存
当 this 的对象时递增
类创建并减少时
它被毁了。这需要一个
名为 #{table_name}_count 的列(例如
作为所有物的 comments_count
注释类)用于
关联类(例如 Post
班级)。您还可以指定自定义
通过提供一个计数器缓存列
列名称而不是 true/false
此选项的值(例如,
:counter_cache => :我的自定义计数器。)
注意:指定计数器缓存将
将其添加到该模型的列表中
只读属性使用
attr_readonly。

这里是 ryan bates railscasts 位于 counter_cache 上。

此处 是我半年前提出的一个问题的答案,其中的解决方案是一个易于实现的自制计数器缓存。

To expand on Devenv's answer counter cache is what you would typically use for this kind of scenario.

From the api docs:

Caches the number of belonging objects
on the associate class through the use
of increment_counter and
decrement_counter. The counter cache
is incremented when an object of this
class is created and decremented when
it‘s destroyed. This requires that a
column named #{table_name}_count (such
as comments_count for a belonging
Comment class) is used on the
associate class (such as a Post
class). You can also specify a custom
counter cache column by providing a
column name instead of a true/false
value to this option (e.g.,
:counter_cache => :my_custom_counter.)
Note: Specifying a counter cache will
add it to that model‘s list of
readonly attributes using
attr_readonly.

Here is a screen cast from ryan bates' railscasts on counter_cache.

Here is an answer to a question I asked half a year ago where the solution was an easily implemented home-brew counter cache.

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