Rails 请教 view 里面的优化

icemark · March 18, 2012 · Last by icemark replied at March 21, 2012 · 3133 hits

产品拥有多个图片 列表展示的时候使用第一张图片作为缩略图 image_tag product.previews.first.photo_url.to_s 从 product 到 previews 到 first 是不是也算把逻辑放到 view 里面了?导致 view 的解析慢了

能够有更好的处理方法?

慢的原因是不因为你把逻辑方 View 里面了,而是 product.previews 这么调用带出了另外个查询。

是的,我就是想请教这种情况如何优化

查 product 的时候 includes(:previews)

previews.first 会从数据库拿到所有的 previews,最好专门建立 first_preview 方法,只从数据库返回一条,另外查看一下是否建立了索引。

谢谢,已经建立了索引了 eager loading 可以解决这个问题

优化前 N+1 条查询在 view 里面: Completed 200 OK in 137ms (Views: 108.5ms | ActiveRecord: 1.7ms) 优化后,2 条查询: Completed 200 OK in 165ms (Views: 18.1ms | ActiveRecord: 5.2ms) 查询总时间增加了,view 里面没有查询之后 快了很多

#7 楼 @icemark 但是,你还是得听 @nouse 的建议,你现在快了,那是因为数据少

#8 楼 @huacnlee 请教 huacnlee , nouse 不知道你们建议的方法应该如何写?我的写法反而查询次数多了 model 里面 first_preview 方法定义:

has_many :first_preview, :class_name => 'Preview', :limit => 1

新写法如下

@themes = Theme.includes(:first_preview)......m

修改前执行结果:

Theme Load (0.2ms)  SELECT `themes`.* FROM `themes` ORDER BY remseq, updated_at DESC
 Preview Load (4.5ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id IN (69,107,106,98,96,61,62))

修改后执行结果:

Theme Load (2.6ms)  SELECT `themes`.* FROM `themes` ORDER BY remseq, updated_at DESC
 Preview Load (4.2ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id IN (69,107,98,61,62))
 Preview Load (0.1ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 80) LIMIT 1
 CACHE (0.0ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 80) LIMIT 1
 Preview Load (0.1ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 97) LIMIT 1
 CACHE (0.0ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 97) LIMIT 1
 Preview Load (0.1ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 66) LIMIT 1
 CACHE (0.0ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 66) LIMIT 1
 Preview Load (0.1ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 12) LIMIT 1
 CACHE (0.0ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 12) LIMIT 1
 Preview Load (0.1ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 72) LIMIT 1
 CACHE (0.0ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 72) LIMIT 1
 Preview Load (0.1ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 65) LIMIT 1
 CACHE (0.0ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 65) LIMIT 1
 Preview Load (0.1ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 91) LIMIT 1
 CACHE (0.0ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 91) LIMIT 1
 Preview Load (0.1ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 71) LIMIT 1
 CACHE (0.0ms)  SELECT `previews`.* FROM `previews` WHERE (`previews`.theme_id = 71) LIMIT 1


You need to Sign in before reply, if you don't have an account, please Sign up first.