我必须优化此方法,因为处理1000个对象2-3秒
def children_progress
descendants_array = descendants
descendants = self.class.where(id: descendants_array.map(&:id))
max_level = descendants.maximum(:level)
descendants_leaves = descendants.where(level: max_level)
if descendants_leaves.any?
descendants_leaves_id = descendants_leaves.pluck(:id)
node_ids = Plans::CategoriesNode.where(category_id: descendants_leaves_id).pluck(:node_id)
nodes = Plans::Node.where(id: node_ids)
nodes.average(:progress).to_f
else
0
end
结束
我知道这些小改进:
有可能优化在哪里?还要别的吗?这需要不到一秒钟。谢谢!!!
而不是运行相当于where(category_id: descendants_leaves.pluck(:id))
,尝试where(category_id: descendants_leaves.select(:id))
。 ActiveRecord会将.select()
作为category_id IN (SELECT id FROM ...)
插入SQL。这样你只有一个外部的SELECT语句,而不是两个,并且map
ping所有第一个id
s到Ruby变量的开销。