我必须优化此方法,因为需要处理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
端
我知道这些小改进:
可以优化哪里?还要别的吗?这需要不到一秒钟。感谢!!!
答案 0 :(得分:0)
请尝试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
的开销将所有第一个id
ping到Ruby变量中。