如何避免在 Rails 中使用 :include 进行多次查询? [英] How do I avoid multiple queries with :include in Rails?

查看:12
本文介绍了如何避免在 Rails 中使用 :include 进行多次查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我这样做

post = Post.find_by_id(post_id, :include => :comments)

执行两个查询(一个用于帖子数据,另一个用于帖子的评论).然后当我做 post.comments 时,没有执行另一个查询,因为数据已经缓存了.

two queries are performed (one for post data and and another for the post's comments). Then when I do post.comments, another query is not performed because data is already cached.

有没有办法只做一个查询,并且仍然通过 post.comments 访问评论?

Is there a way to do just one query and still access the comments via post.comments?

推荐答案

不,没有.这是 :include 的预期行为,因为 JOIN 方法最终证明是低效的.

No, there is not. This is the intended behavior of :include, since the JOIN approach ultimately comes out to be inefficient.

例如,考虑以下场景:Post 模型有 3 个您需要选择的字段,Comment 的 2 个字段,并且此特定帖子有 100 条评论.Rails 可以按照以下方式运行单个 JOIN 查询:

For example, consider the following scenario: the Post model has 3 fields that you need to select, 2 fields for Comment, and this particular post has 100 comments. Rails could run a single JOIN query along the lines of:

SELECT post.id, post.title, post.author_id, comment.id, comment.body
FROM posts
INNER JOIN comments ON comment.post_id = post.id
WHERE post.id = 1

这将返回以下结果表:

 post.id | post.title | post.author_id | comment.id | comment.body
---------+------------+----------------+------------+--------------
       1 | Hello!     |              1 |          1 | First!
       1 | Hello!     |              1 |          2 | Second!
       1 | Hello!     |              1 |          3 | Third!
       1 | Hello!     |              1 |          4 | Fourth!
...96 more...

您已经可以看到问题了.单查询JOIN 方法,虽然它返回你需要的数据,但返回它是多余的.当数据库服务器将结果集发送到 Rails 时,它将分别发送帖子的 ID、标题和作者 ID 100 次.现在,假设 Post 有 10 个您感兴趣的字段,其中 8 个是文本块.呃.这是很多数据.将数据从数据库传输到 Rails 确实需要双方的工作,包括 CPU 周期和 RAM,因此最大限度地减少数据传输对于使应用程序运行得更快更精简很重要.

You can see the problem already. The single-query JOIN approach, though it returns the data you need, returns it redundantly. When the database server sends the result set to Rails, it will send the post's ID, title, and author ID 100 times each. Now, suppose that the Post had 10 fields you were interested in, 8 of which were text blocks. Eww. That's a lot of data. Transferring data from the database to Rails does take work on both sides, both in CPU cycles and RAM, so minimizing that data transfer is important for making the app run faster and leaner.

Rails 开发人员处理了这些数字,并且大多数应用程序在使用多个查询时运行得更好,这些查询只获取每一位数据一次,而不是一个有可能变得非常冗余的查询.

The Rails devs crunched the numbers, and most applications run better when using multiple queries that only fetch each bit of data once rather than one query that has the potential to get hugely redundant.

当然,在每个开发人员的生活中,都会有一个时候需要加入才能运行复杂的条件,这可以通过将 :include 替换为 :joins.然而,对于预取关系,Rails 在 :include 中采用的方法在性能方面要好得多.

Of course, there comes a time in every developer's life when a join is necessary in order to run complex conditions, and that can be achieved by replacing :include with :joins. For prefetching relationships, however, the approach Rails takes in :include is much better for performance.

这篇关于如何避免在 Rails 中使用 :include 进行多次查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆