在过期查询上迭代和更新时了解SQLAlchemy性能

2024-05-23 18:35:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我在SQLAlchemy中迭代一个查询并对行执行更新,我发现性能出人意料地差,速度比我预期的要慢几个数量级。数据库大约有12K行。我最初的查询和循环如下所示:

query_all = session.query(MasterImages).all()

for record_counter, record in enumerate(query_all):
    # Some stuff happens here, set_id and set_index are defined
    session.query(MasterImages).\
            filter(MasterImages.id == record.id).\
            update({'set_id':set_id, 'set_index':set_index})
    if record_counter % 100 == 0:
        session.commit()
        print 'Updated {:,} records'.format(record_counter)
session.commit()

循环中的第一次迭代非常快,但在第一次提交之后似乎会停止。我尝试了很多不同的方法,但都没有成功。然后我尝试更改我的查询,这样它只选择了计算我在更新中使用的set_id和{}值所需的字段,如下所示:

^{pr2}$

这就产生了我期待的表演,在不到一分钟的时间里就把所有的唱片都翻了一遍。在考虑了一段时间后,我认为我的问题是,在提交之后的第一个查询中,由于我更新了我正在迭代的查询中(不必要的)的一个字段,所以变成了一个过时的查询。我认为,这迫使Alchemy在每次提交后重新生成查询。通过删除我正在迭代的查询中更新的字段,我想我可以使用相同的查询,这导致了我的性能提高。在

我说的对吗?在


Tags: idindexsqlalchemysessioncounterall性能record
1条回答
网友
1楼 · 发布于 2024-05-23 18:35:55

关闭^{}。在

expire_on_commit打开的情况下,SQLAlchemy会在.commit()之后将查询中的所有对象标记为过期(或如您所说的“过时”)。过期意味着下次尝试访问对象的属性时,SQLAlchemy将发出SELECT来刷新对象。关闭“提交时过期”将阻止它这样做。expire\u\u commit是一个选项,这样就不会破坏ORM的幼稚使用,所以如果您知道自己在做什么,就可以安全地关闭它。在

您的修复是有效的,因为当您指定列时(主图像.id,等)而不是query()中的映射类(MasterImages),SQLAlchemy返回一个普通python元组,而不是映射类的实例。元组不提供ORM特性,也就是说,它不会过期,并且永远不会从数据库中重新获取自己。在

相关问题 更多 >