【发布时间】:2019-08-23 12:48:59
【问题描述】:
在 postgresql 中工作我有一个笛卡尔连接,产生了大约 400 万行。 连接需要约 5 秒,写回数据库需要约 1 分 45 秒。
这些数据需要在 python 中使用,特别是在 pandas 数据框中,所以我正在尝试在 python 中复制相同的数据。我应该在这里说所有这些测试都在一台机器上运行,所以没有任何东西通过网络。
使用 psycopg2 和 pandas,读入数据并执行连接以获得 400 万行(来自此处的答案:cartesian product in pandas)始终花费不到 3 秒,令人印象深刻。
然而,将数据写回数据库中的表需要 8 分钟(最佳方法)到 36 分钟以上(加上一些我拒绝的方法,因为我不得不在 >1 小时后停止它们)。
虽然我不希望重现“仅 sql”时间,但我希望能够接近 8 分钟(我认为 3-5 分钟不会不合理)。
较慢的方法包括:
36 分钟 - sqlalchemy 的 table.insert(来自此处的“test_sqlalchemy_core”https://docs.sqlalchemy.org/en/latest/faq/performance.html#i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow)
13 分钟 - psycopg2.extras.execute_batch (https://stackoverflow.com/a/52124686/3979391)
13-15 分钟(取决于块大小)- pandas.dataframe.to_sql(再次使用 sqlalchemy)(https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html)
最好的方法(约 8 分钟)是使用 psycopg2 的 cursor.copy_from 方法(在这里找到:https://github.com/blaze/odo/issues/614#issuecomment-428332541)。 这涉及首先将数据转储到 csv(通过 io.StringIO 在内存中),仅此一项就需要 2 分钟。
所以,我的问题:
1) 任何人有任何可能更快的方法将数百万行从 pandas 数据帧写入 postgresql?
2) cursor.copy_from 方法 (http://initd.org/psycopg/docs/cursor.html) 的文档指出源对象需要支持 read() 和 readline() 方法(因此需要 io.StringIO)。据推测,如果数据帧支持这些方法,我们可以省去对 csv 的写入。有没有办法添加这些方法?
谢谢。 贾尔斯
【问题讨论】:
-
这能回答你的问题吗? Write fast pandas dataframe to postgres
-
我将此标记为重复,尽管您的问题有很多关于不同方法速度的有价值信息。如果可能,请将其添加到关于该问题的问答中!
-
谢谢,看起来答案是使用我上面的“最佳方法”。我已通过此处的链接在已接受的答案中添加了评论,以防它对任何人有所帮助。
-
另外,不相信这是重复的 - 另一个是“你能加快这段代码的速度吗”,而这是“什么是最快的方法”。
标签: python pandas postgresql dataframe sqlalchemy