python - 优化mysql多次更新

标签 python mysql sqlalchemy sql-update innodb

我正在尝试优化超过 300 万行的单列更新。 列数据存储在 pandas dataframe 中(行 sql 索引已知) 目前我使用的代码是(使用sqlalchemy进行连接)

    conn = getConnection(db).connect()
    trans = conn.begin()
    try:
        i=0
        for index, row in data.iterrows():
            if not np.isnan(row[colName]):
                i+=1
                sql = 'update data set `{0}`= {1} where data_id={2};'.format(colName, row[colName], index)
                conn.execute(sql)
            if i>10000:
                i = 0
                trans.commit()
                trans = conn.begin()
        trans.commit()
    except Exception as e:
        trans.rollback()
    conn.close()

这里是一些innodb变量

innodb_buffer_pool_size = 402653184
innodb_io_capacity = 200

由于目前我遇到了触发回滚的情况,因此如何优化此代码。

最佳答案

10K 是一个不合理的大块。

UPDATE 做了很多事情

  1. 解析语句并决定查询计划。
  2. 准备回滚(复制更新前的行);
  3. 更新行(读取、修改、写入);
  4. 将任何辅助索引更改添加到更改缓冲区,这最终需要导致写入索引。

我建议每个簇不要超过 1000 个(即每个 COMMIT)。 1000 和 10000 之间的效率差异(假设没有超时)可能小于 1%。

当前代码每次迭代都会执行所有 4 个步骤。

建议构建一个 tmp 表,然后使用多表 UPDATE 进行更新可能会更快,也可能不会更快:

  • 需要CREATE等临时表(一次/丛)
  • 插入簇的值或行。这可以(并且应该)优化为包含大量行的单个 INSERT 语句。 (我再次建议不要超过 1000 个。)如果这是“事务性”表类型,那么这里也需要考虑ROLLBACK
  • 您保存了#1(解析),但仍然需要为更新的每一行执行#2-4。

无论如何,这都是更多的代码。将 10000 更改为 1000 是对您的问题的简单而有效的答案。

关于python - 优化mysql多次更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50884857/

相关文章:

python - SQLAlchemy 事务与 session 的正确顺序是什么?

MySQL UNION SELECT 语句按两个不同的列排序

php - 将表单插入数据库

python - matplotlib 中的补丁轮换未按预期运行

javascript - 如何将经度和纬度转换为街道地址

MySQL:嵌入式 JSON 与表

Mysql 连接过多 : Django sqlAlchemy

python - flask-login 仅在 get_id() 返回 self.email 时有效

python - 使用 XMLRPC 在 Python 中进行动态函数调用

python - 如何批量更新Elasticsearch中的字段?