gpt4 book ai didi

python - 迭代过期查询和更新时了解 SQLAlchemy 性能

转载 作者:行者123 更新时间:2023-11-30 23:06:16 25 4
gpt4 key购买 nike

我在 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_idset_index 值,如下所示:

query_all = session.query(MasterImages.id, MasterImages.project_id, 
MasterImages.visit, MasterImages.orbit,
MasterImages.drz_mode, MasterImages.cr_mode).all()

这产生了我预期的性能,在不到一分钟的时间内翻遍了所有记录。考虑了一段时间后,我认为我的问题是在我的第一个查询中,在提交之后,变成了一个陈旧的查询,因为我已经更新了一个字段,这个字段(不必要地)在我正在迭代的查询中。我认为,这迫使 Alchemy 在每次提交后重新生成查询。通过从我正在迭代的查询中删除我正在更新的字段,我认为我能够使用相同的查询,这导致我的性能提高。

我说的对吗?

最佳答案

关闭 expire_on_commit .

启用 expire_on_commit 后,SQLAlchemy 在 .commit() 之后将 query_all 中的所有对象标记为已过期(或如您所说的“陈旧”)。过期意味着下次您尝试访问对象上的属性时,SQLAlchemy 将发出 SELECT 以刷新对象。关闭 expire_on_commit 将阻止它这样做。 expire_on_commit 是一个选项,因此 ORM 的天真使用不会被破坏,所以如果你知道你在做什么,你可以安全地关闭它。

您的修复工作有效,因为当您在 query() 中指定列(MasterImages.id 等)而不是映射类 (MasterImages) 时,SQLAlchemy 返回给您一个普通的 python 元组而不是映射类的实例。该元组不提供 ORM 功能,即它不会过期并且永远不会从数据库中重新获取自身。

关于python - 迭代过期查询和更新时了解 SQLAlchemy 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21766023/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com