我有一个Ruby / Sinatra应用程序,我正在接收和解析JSON字符串,例如:
[{"id" => "ABCD123", "type" => "image"},
{"id" => "ABCD234", "type" => "image"},
{"id" => "ABCD345", "type" => "image"},
{"id" => "ABCD456", "type" => "image"},
{"id" => "ABCD567", "type" => "image"}]
在数据库中,我有许多行存储图像的标题。目前,我有一个迭代数组的函数,并执行以下操作:
app.rb
def get_caption(image_id)
caption = Images.find_by_image_id image_id
end
index.haml
-images.each do |image|
%div= get_caption(image['id'])
这看起来非常低效,因为该网站对每个图像执行了一次独特的查找,这肯定会在页面的加载时间中加起来。
Images Load (131.6ms) SELECT "images".* FROM "images" WHERE "images"."image_id" = 'ABCD123' LIMIT 1
...
Images Load (131.6ms) SELECT "images".* FROM "images" WHERE "images"."image_id" = 'ABCD567' LIMIT 1
131.6ms * n
查询确实很快加起来(我希望这个缓慢的~130ms查询在我们优化生产时也会得到改善,但也许这将是以后的另一个问题!)
有没有更有效的方法来进行此查找?某种方式沿着将caption
字段加入数组的方式?
答案 0 :(得分:2)
您可以采取两项措施来优化这一点:
一次从数据库中获取所有必需的数据,而不是循环:
Images.where(image_id: image_ids).index_by(&:image_id)
在数据库的image_id
列中创建二级索引:
add_index :images, :image_id
我想强调的其他一些事情违背了Rails的惯例:
Image
。答案 1 :(得分:0)
写为
def get_captions(image_ids)
caption = Images.where(image_id: image_ids)
end
image_ids = images.map { |image| image['id'] }
get_captions(image_ids)