如何提升Flask中关联User、School表的查询效率,避免多次重复查询
你当前需要执行25次独立查询的实现不合理,存在较大的性能浪费,有更优的解决方案,以下是具体落地思路:
方案1:单次查询全量数据+内存分组(推荐)
仅需执行1次SQL查询拿到所有关联了学校的用户数据,再在内存中按「学校类型+用户状态」做分组,即可直接得到25个分组对应的用户列表,大幅降低数据库IO开销。
示例代码如下:
from collections import defaultdict # 单次查询拉取所有关联学校的用户,同时带出分组维度字段 user_groups = defaultdict(list) query_result = ( session.query(User, School.type.label("school_type"), User.status.label("user_status")) .join(School) .all() ) # 内存层按维度分组 for user, school_type, user_status in query_result: user_groups[(school_type, user_status)].append(user) # 调用方式和原有25次查询的结果完全一致,比如取学校类型1、用户状态2的用户 target_users = user_groups.get((1, 2), [])
方案2:分组聚合查询(仅需统计数量的场景适用)
如果你的业务场景不需要获取具体的用户实例,仅需要统计每个分组的用户数量,直接用SQL的分组聚合能力,一次查询返回所有分组的统计结果,性能更高:
from sqlalchemy import func stat_result = ( session.query(School.type, User.status, func.count(User.id).label("user_count")) .join(School) .group_by(School.type, User.status) .all() )
返回结果的每一行对应(学校类型, 用户状态, 对应用户数量)。
特殊场景说明
只有当单组用户数据量极大(比如单组用户数超过10万),单次查询全量数据会超出内存负载时,才可以考虑分批查询。就算是分批场景也不需要执行25次查询,可以通过in条件批量查询多个维度组合,将查询次数控制在个位数即可。
注意:避免在循环中执行SQL查询是ORM使用的通用规范,多次查询会产生不必要的数据库连接占用、IO开销,非极端场景优先选择单次查询+内存分组的方案。
内容的提问来源于stack exchange,提问作者newbir
相关产品推荐
相关产品推荐

