Dataframe 写入 Postgresql 性能不佳

2024-01-06

在 postgresql 中工作,我有一个笛卡尔连接,生成约 400 万行。 连接需要约 5 秒,写回数据库需要约 1 分 45 秒。

这些数据需要在 python 中使用,特别是在 pandas 数据框中,因此我正在尝试在 python 中复制相同的数据。我应该在这里说,所有这些测试都在一台机器上运行,因此没有任何内容通过网络进行。

使用 psycopg2 和 pandas,读入数据并执行连接以获得 400 万行(来自此处的答案:pandas 中的笛卡尔积 https://stackoverflow.com/questions/13269890/cartesian-product-in-pandas)持续花费不到 3 秒,令人印象深刻。

然而,将数据写回数据库中的表需要 8 分钟(最佳方法)到 36 分钟以上(加上我拒绝的一些方法,因为我必须在 >1 小时后停止它们)。

虽然我没想到会重现“仅 sql”时间,但我希望能够接近 8 分钟(我认为 3-5 分钟不会不合理)。

较慢的方法包括:

36分钟 - sqlalchemy`s 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 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 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 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 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 http://initd.org/psycopg/docs/cursor.html)声明源对象需要支持 read() 和 readline() 方法(因此需要 io.StringIO)。据推测,如果数据框支持这些方法,我们就可以省去写入 csv。有什么方法可以添加这些方法吗?

谢谢。 贾尔斯

EDIT:

在第二季度 - pandas 现在可以使用 to_sql 的自定义可调用对象以及此处给出的示例:https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-sql-method https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-sql-method几乎按照我上面的建议进行操作(即它使用 StringIO 直接从 STDIN 复制 csv 数据)。 我发现使用此方法写入速度提高了约 40%,这使 to_sql 接近上面提到的“最佳”方法。


我自己回答问题1: 看来这个问题更多地与 Postgresql(或者更确切地说是数据库)有关。考虑到本文中提出的观点:https://use-the-index-luke.com/sql/dml/insert https://use-the-index-luke.com/sql/dml/insert我发现了以下内容:

1) 从目标表中删除所有索引导致查询在 9 秒内运行。重建索引(在 postgresql 中)又花了 12 秒,所以仍然远远低于其他时间。

2) 在仅存在主键的情况下,插入按主键列排序的行将所需时间减少到大约三分之一。这是有道理的,因为应该很少或不需要对索引行进行改组。我还验证了这就是为什么我在 postgresql 中的笛卡尔连接首先速度更快的原因(IE 行是按索引排序的,纯粹是偶然的),将相同的行放在临时表中(无序)并从中插入实际上花了更长的时间。

3)我在我们的mysql系统上尝试了类似的实验,发现删除索引时插入速度也有同样的提高。然而,对于mysql来说,重建索引似乎耗尽了所获得的任何时间。

我希望这对通过搜索遇到此问题的其他人有所帮助。

我仍然想知道是否可以删除 python 中的写入 csv 步骤(上面的 Q2),因为我相信我可以在 python 中编写比纯 postgresql 更快的东西。

谢谢,贾尔斯

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dataframe 写入 Postgresql 性能不佳 的相关文章

随机推荐

  • Mysql 带游标的存储过程

    Mysql游标问题 我编写了一个存储过程 它将从一个表中获取旅行记录并将其插入到 2 3 个不同的表中 使用插入语句 问题是我正在检查 table1 中是否不存在记录 然后我将记录从 temptable 顺序插入到 table1 table
  • PHP - 检查一个字符串是否是另一个字符串的旋转

    需要编写一个代码块来检查一个字符串是否是另一个字符串的旋转 看了这里的大量帖子 都是用 Java 或 C 写的 但我需要用 PHP 来做 我尝试了一些不同的方法 尝试使用 C 和 Java 示例 但我没有任何运气 这是我当前的代码
  • bx滑块启动/停止功能

    我正在使用 bxslider 插件 并为上一个和下一个功能创建了一些外部控件 尽管我似乎不知道如何对启动 停止控件执行相同的操作 基本上我想用它作为滑块的播放 暂停功能 有人有这个插件的经验吗 这是我到目前为止所拥有的 没有启动 停止功能工
  • 跨域图片上传 Angular+laravel

    我一直在努力在服务器上上传图像 我在用ng文件上传 https github com danialfarid ng file upload在前端 但我总是得到 对预检请求的响应未通过访问控制检查 请求的资源上不存在 Access Contr
  • 如何在 Ruby 中解析带有单引号 (') 的 JSON 字符串?

    我正在尝试解析这样的 JSON 字符串 JSON parse foo 42 但是 这会产生 JSON ParseError JSON ParserError 757 unexpected token at foo 42 from Users
  • 更新插入文档和/或添加子文档

    我一直在努力解决 MongoDB Mongoose 和 JavaScript 的异步特性以及如何最好地对集合进行多次更新 我有一张包含客户和联系人数据的 Excel 表格 有些客户端有多个联系人 每行一个 并且客户端数据是相同的 因此客户端
  • 运行 Leiningen 时出现 java.lang.NoSuchMethodError:clojure.lang.KeywordLookupSite

    我刚刚下载了 Leiningen 但无法运行它 下载自己的 Jar 存档后 脚本失败并出现 java 错误 通过跑步bash x lein我可以看到它挂在这一行 exec java Xbootclasspath a home andrea
  • 如何使用 Swift 构建 ScrollView?

    我正在构建我的第一个 IOS 应用程序 我正在努力寻找一种方法来使用 XCode6 上的 Swift 代码做一个简单的 ScrollView 请问有人可以帮助我找到解决方案吗 我的问题是我不知道如何使滚动视图在我的代码中工作 我已经将代码放
  • 通过 gdal 将多个频段合并在一起...正确

    我正在 python 中使用一些 Sentinel 2 卫星图像 现在我使用较新的 2016 年之前的 没有任何问题 但我需要使用 2016 年的一些 欧洲航天局没有以同样的方式对这些进行预处理 通常 当您下载图块时 您通常会获得每个卫星频
  • 计算字符串中前导空格的 pythonic 方法是什么?

    我知道我可以用这个来计算字符串中的前导空格 gt gt gt a foo bar baz qua n gt gt gt print Leading spaces len a len a lstrip Leading spaces 3 gt
  • 具有椭圆积分和贝塞尔函数的 Java/Scala 数学库?

    我正在寻找一个用于科学计算的数学库 以便在 Java Scala 中使用 特别是我需要完整的椭圆积分和修正的贝塞尔函数 如果它是开源的 我会很高兴 但我想我将不得不采用那里的任何东西 替换 scipy 用于科学计算的 python 库 会很
  • 为什么对原始值使用表达式主体属性? [复制]

    这个问题在这里已经有答案了 表达式主体属性与直接属性声明相比有何优缺点 例如 使用有什么好处吗 public string Foo gt Bar 与简单地 public string Foo Bar 我的理解是 gt 当值来自方法 例如 l
  • 图片上传重力形式预览

    我使用 重力表格 制作了一个联系表格 其中我使用了图像上传器 现在我想向正在上传的用户显示图像的预览 有办法实现这个目标吗 抱歉 迟到的答复
  • XIB中如何根据子视图大小调整超级视图的高度?

    在xcode 6中 我为自定义视图创建了一个xib 名为 ViewA 有红色背景色 ViewA的xib有一个文件大小600 600 在ViewA中 我放置了一个子视图labelB 有绿色背景色 其中 labelB的numberOfLines
  • 为加密狗附加系统编写什么代码才能提供更好的安全性?

    我开发了一个软件 使用 C 和 Python 我想用加密狗对其进行保护 以便复制和逆向工程变得足够困难 我的加密狗设备附带一个 api 它提供以下功能 检查加密狗是否存在 检查正确的加密狗 写入加密狗的内存位置 从加密狗等的内存位置读取 我
  • 如何在方法内使用“this”创建类的新实例?

    我正在寻找一种方法来调用 newthis从类方法内部 class Example fork return new this const x new Example fork instance of example class Alpha e
  • 如何开发适用于手机和平板电脑的 Xamarin 表单应用程序

    1 在Android Java 中 手机和平板电脑有不同的文件夹 Layout布局 大布局 xlarge 2 在 iOS 中 使用通用设置 我还没有尝试过以 Xamarin 形式 我需要一些帮助 如果该应用程序适用于手机和平板电脑 我需要做
  • Pyinstaller:找不到 PyQT5 Web 应用程序的 QtWebEngineProcess.exe

    我正在开发一个显示 folium 地图的 Web 应用程序 该网络应用程序有 3 个选项卡 每个选项卡都有一个QWeb引擎视图小部件添加到其中 我正在尝试为我的 Web 应用程序创建一个独立的 exe 文件 因此 我使用 Pyinstall
  • SuSE 上的 rpmlib(FileDigests) 依赖性错误

    Doing a 百胜安装A 3 6 0在 SuSE 11 2 64 位 和 CentOS 5 8 64 位 上 都会弹出以下安装要求错误 error Failed dependencies rpmlib FileDigests lt 4 6
  • Dataframe 写入 Postgresql 性能不佳

    在 postgresql 中工作 我有一个笛卡尔连接 生成约 400 万行 连接需要约 5 秒 写回数据库需要约 1 分 45 秒 这些数据需要在 python 中使用 特别是在 pandas 数据框中 因此我正在尝试在 python 中复