Rails:包括vs.:连接
这更多的是“为什么这样做”这个问题,而不是“我不知道该怎么做”这个问题......
所以关于拉你知道你将要使用的相关记录的福音是使用:include
因为你会得到一个连接并避免一大堆额外的查询:
Post.all(:include => :comments)
但是,当您查看日志时,不会发生任何联合:
Post Load (3.7ms) SELECT * FROM "posts"
Comment Load (0.2ms) SELECT "comments.*" FROM "comments"
WHERE ("comments".post_id IN (1,2,3,4))
ORDER BY created_at asc)
它采取了一种捷径,因为它一次提取所有的注释,但它仍然不是一个连接(这就是所有文档似乎都说的)。 我可以获得连接的唯一方法是使用:joins
而不是:include
:
Post.all(:joins => :comments)
日志显示:
Post Load (6.0ms) SELECT "posts".* FROM "posts"
INNER JOIN "comments" ON "posts".id = "comments".post_id
我错过了什么吗? 我有一个应用程序与六个协会,并在一个屏幕上显示所有这些数据。 似乎有一个联合查询而不是6个人会更好。 我知道性能方面,并不总是更好地做一个连接而不是单个查询(事实上,如果你花时间去了,看起来上面的两个单独查询比连接快),但是在所有文档我一直在阅读,我很惊讶地看到:include
不按广告方式工作。
也许Rails认识到性能问题,除非在某些情况下不加入?
看来, :include
功能在Rails 2.1中发生了变化。 在所有情况下,Rails用于执行连接,但出于性能方面的原因,它在一些情况下更改为使用多个查询。 Fabio Akita的这篇博客文章提供了一些有关这一变化的良好信息(请参阅标题为“Optimized Eager Loading”的部分)。
.joins
只会加入表格并返回选定的字段。 如果您在联接查询结果时调用关联,它将再次触发数据库查询
:includes
将加载包含的关联并将它们添加到内存中。 :includes
加载所有包含的表格属性。 如果您在包含查询结果上调用关联,则不会触发任何查询
我的博客文章对这些差异有一些详细的解释
连接和包含的区别在于,使用include语句会生成一个更大的SQL查询,将其他表中的所有属性加载到内存中。
例如,如果您的表格中充满了评论,并且您使用:joins =>用户为了排序目的而提取所有用户信息等,它可以正常工作,所需时间少于include:但是假设您想要显示注释以及用户名称,电子邮件等。要使用连接来获取信息,它必须为它提取的每个用户分别执行SQL查询,而如果您使用了:include,则此信息已准备就绪可供使用。
很好的例子:
http://railscasts.com/episodes/181-include-vs-joins
链接地址: http://www.djcxy.com/p/25813.html