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

前端之家收集整理的这篇文章主要介绍了java – 使用JDBC在PostgreSQL上缓慢插入前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在一个从云系统向本地数据库(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中禁用调用)

猜你在找的Java相关文章