【问题标题】:Improve query performance提高查询性能
【发布时间】:2013-08-03 14:37:07
【问题描述】:

我需要从 PostgreSQL 数据库中读取和连接很多行(约 500k)并将它们写入 MySQL 数据库。

我的幼稚做法是这样的

    entrys = Entry.query.yield_per(500)

    for entry in entrys:
        for location in entry.locations:
            mysql_location = MySQLLocation(entry.url)
            mysql_location.id = location.id
            mysql_location.entry_id = entry.id

            [...]

            mysql_location.city = location.city.name
            mysql_location.county = location.county.name
            mysql_location.state = location.state.name
            mysql_location.country = location.country.name

            db.session.add(mysql_location)

    db.session.commit()

每个Entry 大约有1 到100 个Locations

这个脚本现在运行了大约 20 个小时,并且已经消耗了超过 4GB 的内存,因为所有内容都保存在内存中直到会话提交。

通过我之前提交的尝试,我遇到了this 之类的问题。

如何提高查询性能?它需要变得更快,因为在接下来的几个月中行数将增长到大约 2500k。

【问题讨论】:

  • 有什么理由不能使用Extract, Transform, Load 方法?
  • 基本上pg_dump dbname | mysql dbname
  • @JochenRitzel,我将多个表中的多行合并为 MySQL 的一行。我不明白 pg_dump 有什么帮助。
  • 您是否尝试过将 Postgres 中的数据提取到 CSV 并将 CSV 加载到 MySQL 中?

标签: python mysql postgresql sqlalchemy flask-sqlalchemy


【解决方案1】:

由于您已经知道的原因,您的幼稚方法存在缺陷 - 消耗您的内存的东西是悬在内存中等待刷新到 mysql 的模型对象。

最简单的方法是根本不使用 ORM 进行转换操作。直接使用 SQLAlchemy 表对象,因为它们也快得多。

另外,您可以创建 2 个会话,并将 2 个引擎绑定到单独的会话中!然后你可以为每个批次提交 mysql 会话。

【讨论】:

  • 我支持带有 2 个单独会话的选项,其中一个可以使用 expunge_all() 在每个批次中清理它们。此外,您 (@dbanck) 遇到的问题也可以使用范围查询而不是 yield_per 来回答。
猜你喜欢
  • 2021-08-03
  • 2013-02-17
  • 2021-12-15
  • 2014-04-09
  • 2013-01-16
  • 2013-09-26
  • 2011-12-03
  • 2014-04-04
相关资源
最近更新 更多