2011-05-20 43 views
1

在Rails控制器的动作我打电话慢找到包括多个关联

@grid = Grid.find(params[:id], :include => [:grid_properties, :grid_entities => [:entity => :properties]]) 

不幸的是它需要很长的。 Benchmark.realtime(在开发模式下)告诉我1.8812830448150635,所以大概2秒(Rails 3.0.7,Postgres 8.4)。

当在SQL日志我得到这行代码下面转向:

Grid Load (0.9ms) SELECT "grids".* FROM "grids" WHERE "grids"."id" = 2 LIMIT 1 
GridProperty Load (2.5ms) SELECT "grid_properties".* FROM "grid_properties" WHERE ("grid_properties".grid_id = 2) ORDER BY row_order 
GridEntity Load (1.3ms) SELECT "grid_entities".* FROM "grid_entities" WHERE ("grid_entities".grid_id = 2) ORDER BY row_order 
Entity Load (3.0ms) SELECT "entities".* FROM "entities" WHERE ("entities"."id" IN (28,7,3,6,25,11,2,12)) 
Property Load (6.4ms) SELECT "properties".* FROM "properties" WHERE ("properties".entity_id IN (28,7,3,6,25,11,2,12)) 

每个数据库的访问似乎是在低毫秒范围内。为什么最后需要这么长时间?

+0

“Benchmark.realtime”仅用于查询还是包含渲染部分和模板所需的时间? – Wukerplank 2011-05-20 10:33:36

+0

就在上面找到。没有其他包含。 – Zardoz 2011-05-20 10:50:14

回答

1

我想,时间花在Ruby创建对象上。该网格中有多少个属性? 'SELECT FROM properties'的时间看起来相对较高。

你可以进一步调查的问题,如果你有一些功能,你可以将检查点 - logger.debug "CHECKPOINT: #{Time.now} #{caller(0).first}"

你有任何“ON_LOAD”回调,也许?

+0

每个实体大约有50个属性,但没有on_load回调。 Puh,这几乎是创建一些Ruby对象的时间(但我没有任何比较值)。也许我应该直接访问数据而根本不创建Ruby对象。 – Zardoz 2011-05-20 12:13:08

+0

直接访问肯定会更快,但代码的可读性会降低(大多数情况下)。如果你有很好的测试覆盖率,那么它应该是安全的。加载此数据时,您可能还需要测量内存使用情况。 Maye会显示一些有趣的内容吗? – Arsen7 2011-05-20 12:42:57

+0

内存使用也没什么特别的。每个属性只包含5个字符串字段,其中每个字段包含大多数小于50个字符。所以我猜想多重关联的原因并不是ActiveRecord的一个好用例。我会尝试直接访问数据,看看它有什么不同。谢谢您的帮助。 – Zardoz 2011-05-20 13:00:24