在大量查询结果的循环中,更新操作花费了奇怪的时间

时间:2014-12-10 14:03:55

标签: python orm flask sqlalchemy flask-sqlalchemy

当我查询大量记录时,然后循环结果。 如果我更新一条记录,将花费很多时间。

_users = db.session.query(WxUser).limit(10000).all()
for _user in _users:
    t1 = time()
    db.session.query(WxUser).filter_by(id=_user.id).update(dict(sex=WxUser.Sex.MALE))
    db.session.commit()
    t2 = time()
    print t2 - t1

out put:

0.242075920105
15.5323040485
16.6957418919

提交操作的成本时间比正常情况多。 当打开' SQLALCHEMY_ECHO'时,表明SQLAlchemy按id查询每条记录。

怎么回事?

1 个答案:

答案 0 :(得分:0)

https://bitbucket.org/zzzeek/sqlalchemy/issue/3270/in-the-loop-of-large-quantity-query-result

我问SQLAlchemy作者。 他给出了答案:

两种技巧将解决花费的时间。

  1. 转换对象的Python内部评估以查看它们是否符合条件:

    s.query(WxUser).filter_by(id = _user.id).update(dict(data ='M'),synchronize_session = False)

  2. docs:http://docs.sqlalchemy.org/en/rel_0_9/orm/query.html?highlight=query.update#sqlalchemy.orm.query.Query.update.params.synchronize_session

    1. 在调用update()之前不会使会话中的所有10000个对象失效,这表示为了使上述synchronize_session ='evaulate'起作用,它必须命中每个WxUser对象并评估它们的“ id“,这需要从数据库重新加载:

      session = Session(expire_on_commit = False)

    2. docs:http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html#committing