加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用JDBC在PostgreSQL上缓慢插入

发布时间:2020-12-14 16:35:07 所属栏目:Java 来源:网络整理
导读:我在一个从云系统向本地数据库(PostgreSQL,MySQL,…)下载数据的系统上工作.现在我有一个PostgreSQL性能问题,因为它需要很多时间来插入数据. 许多列和数据的大小可能会有所不同.在一个示例项目中,我有一张约有170列.有一个唯一的索引 – 即使在删除索引后,插
我在一个从云系统向本地数据库(PostgreSQL,MySQL,…)下载数据的系统上工作.现在我有一个PostgreSQL性能问题,因为它需要很多时间来插入数据.

许多列和数据的大小可能会有所不同.在一个示例项目中,我有一张约有170列.有一个唯一的索引 – 即使在删除索引后,插入的速度也没有改变.

我正在使用JDBC驱动程序连接到数据库,并且我以250行的批量插入数据(使用NamedParameterJdbcTemplate).

我花了大约18秒在Postgres上插入数据. MySQL上相同的数据集只需一秒钟.这是一个巨大的区别 – 它来自哪里? Postgres的JDBC驱动程序慢吗?可以用某种方式配置来使其更快吗?我还想念别的吗Postgres和MySQL之间的区别是如此巨大.任何其他想法如何使其更快?

我做了一个可以在Github – https://github.com/varad/postgresql-vs-mysql上提供的示例项目.一切都发生在LetsGo class的“运行”方法中.

解决方法

似乎这是一个Spring“bug”和驱动程序“bug”的组合.

每次调用setValue()时,Spring都会尝试确定列的数据类型.它通过调用PreparedStatementMetaData.getParameterMetaData()

这显然会导致一个“准备”语句被发送到数据库本身,它本身是非常快的(从不超过我的笔记本电脑上的1ms),但是它被称为每行的每一列这总结了很多时间(它是呼叫每个非空值,导致约23.000个呼叫)

在某种程度上这更是一个Spring bug,那么一个驱动程序的bug,因为没有缓存参数元数据并不真正有意义(至少在我看来). MySQL JDBC驱动程序不支持getParameterMetaData(),Spring知道这一点,所以这个“bug”不会显示在MySQL中,因为Spring永远不会调用该方法.

我不知道Postgres的JDBC驱动程序行为是否可以归类为一个错误,但如果驱动程序在第一次调用后缓存该元数据,那肯定会很好.

Spring可以说服不通过属性spring.jdbc.getParameterType.ignore获取语句元数据

所以放:

System.setProperty("spring.jdbc.getParameterType.ignore","true");

前线:

LetsGo letsGo = new LetsGo();

此行为被禁用.

必须在Spring初始化之前设置该属性.

当我使用您的示例项目执行此操作时,插入在笔记本电脑上运行500ms.

编辑

在看到关于使用Postgres-NG驱动程序的意见之后,我将其打入“官方”驱动程序和NG驱动程序的源代码,而NG驱动程序在第一次调用后会缓存参数元数据,而官方驱动程序不会解释了为什么使用NG驱动程序要快得多(没有在Spring中禁用调用)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读