又一个新手问题......
假设我在声明模式下有一个用户表:
class User(Base):
__tablename__ = 'user'
id = Column(u'id', Integer(), primary_key=True)
name = Column(u'name', String(50))
当我有一个用户标识符列表时,我从db获取它们:
user_ids = [1, 2, 3, 4, 5]
users = Session.query(User).filter(User.id.in_(user_ids)).all()
我不喜欢使用in_
,因为我认为我在索引字段上表现不佳
(是真/假?)。
无论如何,有更好的方法来进行查询吗?
谢谢!
编辑:我正在使用MySQL
如何使用OR与sqlalchemy编写此查询?
重新编辑:得到它:
from sqlalchemy.sql.expression import or_
user_ids = [1, 2, 3, 4, 5]
clauses = or_( *[User.user_id==x for x in users] )
users = Session.query(User).filter(clauses).all()
答案 0 :(得分:4)
许多性能问题依赖于数据库引擎。本文的其余部分将涉及MySQL。
IN()子句在索引字段上可能有不良性能,但在您给出的示例中不会。最多一定数量的user_id,您的查询将是最快的。但是,在某些时候,将user_ids放入临时表并加入其中会变得更快。您可以在MySQL here中查看有关IN()与临时表的性能的更多详细信息。
如果user_ids列表基于用户的某些属性(例如管理员或无效),那么您可以在User表中添加一个字段,并完全避免此问题。
答案 1 :(得分:3)
使用“in”子句的替代方法是“或”id,即“id = 1或id = 2或id = 3”。如果只有少数你可能会以这种方式获得一些速度。
来自文档:http://www.sqlalchemy.org/docs/ormtutorial.html#common-filter-operators
from sqlalchemy import or_ filter(or_(User.name == 'ed', User.name == 'wendy'))
您没有说出您正在使用的DBM,但您的管理员可能是您最好的资产。了解要使用的构造的最佳方法是分析查询并尝试几个不同的构造,以便了解特定数据库引擎处理各种查询的情况。无论你使用什么数据库,如果它支持“或”或“in”,你可能会使用它们获得很大的速度,而不是循环遍历你需要的所有id并进行单独的查询。
可能会发现,与更改代码的其他部分相比,担心是否使用“in”或其他构造并不会对应用程序的整体速度产生很大影响。数据库引擎在优化简单查询方面非常狡猾,只要您的查询合理,您就可以获得良好的性能。我们必须学习编程的一个方面是首先使代码运行良好,然后在出现问题时进行测试和优化。通常我们假设我们知道瓶颈在哪里但是分析工具会显示我们错了。使用分析器和基准测试工具可以帮助缩小问题范围,并显示加速任何需要调整的最佳方法。
答案 2 :(得分:0)
@Hadrien(OP)使用过:
from sqlalchemy.sql.expression import or_
user_ids = [1, 2, 3, 4, 5]
clauses = or_( *[User.user_id==x for x in users] )
users = Session.query(User).filter(clauses).all()