产品拥有多个图片 列表展示的时候使用第一张图片作为缩略图 image_tag product.previews.first.photo_url.to_s 从 product 到 previews 到 first 是不是也算把逻辑放到 view 里面了?导致 view 的解析慢了
能够有更好的处理方法?
previews.first 会从数据库拿到所有的 previews,最好专门建立 first_preview 方法,只从数据库返回一条,另外查看一下是否建立了索引。
优化前 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 里面没有查询之后 快了很多
#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