如何让FastAPI/SQLAlchemy复用过滤器优化多查询性能?
优化数据库查询性能:复用ID过滤条件
数据库表结构
id | name | pet ---+------+---- 1 | foo | dog 1 | bar | cat 2 | foo | bird
当前实现代码
def get_pets(id_, list_of_names): PETS = [] for name in list_of_names: query = select(TableModel.pet).filter(TableModel.id == id_).filter(TableModel.name == name) PETS.append(session.execute(query)) return PETS
问题
当前代码会对每个name发起单独查询,每次都重复执行相同的id过滤逻辑,导致数据库做了大量重复计算,存在明显性能冗余。需要优化查询逻辑,让数据库先完成一次ID过滤,再批量匹配指定的name集合。
优化方案
可以通过单次查询同时过滤ID和name集合的方式解决,利用SQLAlchemy的in_操作符匹配多个name,让数据库只需执行一次ID过滤,再批量匹配目标name,大幅降低查询开销:
优化后的代码
def get_pets(id_, list_of_names): # 单次查询完成ID过滤+多name匹配 query = select(TableModel.name, TableModel.pet).filter( TableModel.id == id_, TableModel.name.in_(list_of_names) ) # 执行查询并获取所有结果 results = session.execute(query).fetchall() # 将结果转为name对应pet的字典,方便快速映射 pet_map = {name: pet for name, pet in results} # 按输入的name顺序返回对应pet,无匹配则返回None return [pet_map.get(name) for name in list_of_names]
优化说明
- 减少查询次数:从N次查询(N为name数量)压缩到1次,避免多次数据库连接和重复的ID过滤操作。
- 复用ID过滤逻辑:数据库仅执行一次
id == id_的过滤,再通过in_批量匹配所有指定name,消除重复计算。 - 结果更易使用:通过字典映射整理结果,既能快速匹配输入的name顺序,也方便单独查询某个name对应的pet,更符合API的返回需求。
若需严格对齐原代码的返回格式(每个元素为查询结果对象),可基于单次查询的结果拆分,但通常整理为字典或有序列表的形式更实用。
内容的提问来源于stack exchange,提问作者CutePoison
相关产品推荐
相关产品推荐

