目前,我正在处理一个非常大的mysql2数据库,虽然我已经为我认为合适的字段建立了索引,但某些查询的返回时间非常慢。
我有两个引起问题的模型,Comment和Commenter。
现在,在Commenter和Comment之间有一个has_many关系,但是我的查询依赖于找到每个评论的用户名。因此,我将运行如下代码:
c = Blog.first.comments ##this bit runs fine, I indexed the "blog_id" field on Comments
c.collect {|c| c.commenter.username}为了帮助解决速度问题,我在评论模型的commenter_id字段上创建了一个索引。但是它仍然运行得很慢..
有没有人知道我可以做些什么来帮助提高查询的速度?
发布于 2011-12-20 04:51:51
我使用eager解决了这个问题,这不是RaskolnikOFF发布的链接,而是rails-cast在它之前发布的链接,http://railscasts.com/episodes/22-eager-loading (仍然给了你一个赞成票,因为它把我带到了答案)
显然,我要找的是以下内容:
b = Blog.find(:first, :include=>{:comments => :commenter})
b.comments.collect {|c| c.commenter.username}第一行加载第一个blog及其所有关系(并返回blog)。因此,当我调用第二行时,所有内容都已加载并等待访问。
这比我最初做的工作要好得多。
发布于 2011-12-20 00:08:13
当您想要查找给定commenter_id的评论(“查找乔所做的所有评论”)时,commenter_id上的索引会有所帮助。
但是,当您执行c.commenter时,您搜索的是用户,大概是id等于评论的commenter_id的用户。id列上应该已经有一个索引。确定的方法是获取实际生成的sql语句(在开发中,这些语句是用development.log编写的),并对它们使用explain,例如
explain select * from comments where id = 12345考虑到在没有索引的情况下创建表的id列的可能性很小,最有可能的罪魁祸首是急于加载-如果一篇帖子有500条评论,那么上面的代码将逐个获取相关的用户,并且这500次到数据库的往返加起来
c.includes(:commenter).collect {...}或
c.eager_load(:commenter).collect {...}将解决这个问题(上面的代码片段假设您使用的是Rails3)。
发布于 2011-12-20 02:17:56
Collect将为每个评论者加载ActiveRecord对象,每次加载一个字段。Including / Eager将使用一个查询加载它们,这将有助于提高速度,但如果您希望获得绝对最佳的性能,并且只需要名称,那么您最好更直接地使用SQL,并使用一些可以调优的东西:
c = Blog.first.comments
user_ids = c.collect(&:commenter_id)
usernames = Commenter.where(['commenter_id IN (?)',user_ids]).select('username').collect(&:username)https://stackoverflow.com/questions/8561213
复制相似问题