Springboot JPA postgres 性能缓慢

问题描述 投票:0回答:1

我将 Springboot JPA 与 2 个数据库集成。一个是 Oracle,另一个是 postgres 42.6。

我从rest-api获取数据,每个请求中有500条记录,并将其保存在postgres中。大部分数据是更新,很少是插入。

目前在 postgres 中保存 500 条记录大约需要 22 秒。 我的应用程序属性:

spring.datasource.secondary.jndi-name=java:/datasources/IntegratorMasterdataDS
spring.datasource.secondary.driver-class-name=oracle.jdbc.OracleDriver

spring.jpa.secondary.hibernate.dialect = org.hibernate.dialect.OracleDialect


spring.datasource.primary.jndi-name=java:/datasources/ItghPostgresXADS
spring.datasource.primary.driver-class-name=org.postgresql.Driver

我正在做如下配置:

@Primary
@Configuration
@EnableJpaRepositories(basePackages = "com.tietoevry.absolutesoftware.itgh", entityManagerFactoryRef = "itghEntityManager", transactionManagerRef = "itghTransactionManager")
public class ItghAutoConfiguration {

    @Value("${spring.datasource.primary.jndi-name}")
    private String itghJndiDatasourceName;

    @Primary
    @Bean
    public DataSource itghDataSource() {
        JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
        return jndiDataSourceLookup.getDataSource(itghJndiDatasourceName);
    }

    @Primary
    @Bean
    public PlatformTransactionManager itghTransactionManager() {
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        jpaTransactionManager.setEntityManagerFactory(itghEntityManager().getObject());
        
        return jpaTransactionManager;
    }

    @Primary
    @Bean
    public LocalContainerEntityManagerFactoryBean itghEntityManager() {
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource(itghDataSource());
        factoryBean.setPackagesToScan("com.tietoevry.absolutesoftware.itgh");
        factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        
        Map<String,Object> jpaProperties = new HashMap<>();
        jpaProperties.put("hibernate.jdbc.batch_size", 500);
        jpaProperties.put("hibernate.show_sql", true);
        jpaProperties.put("hibernate.generate_statistics", true);

        factoryBean.setJpaPropertyMap(jpaProperties);
        return factoryBean;
    }
}

对于 Oracle 数据库,我正在做同样的事情,但没有 jpaProperties 并将其设为辅助数据库。

@Repository
public interface ApplicationsRepository extends JpaRepository<Applications, String> {}

在列表中添加 500 条记录后我正在呼叫

appRepository.saveAll(applications);
appRepository.flush();

Hibernate 统计信息:根据统计信息,它显示创建了 70 个批次,但为每个选择查询打印 sql,并且每个更新/插入没有批处理。如果我从 jpaProperties 中删除“batch_size”,则需要相同的时间。

Metrics {
    45644216 nanoseconds spent acquiring 1 JDBC connections;
    0 nanoseconds spent releasing 0 JDBC connections;
    950436647 nanoseconds spent preparing 18711 JDBC statements;
    851450529369 nanoseconds spent executing 18641 JDBC statements;
    14912223124 nanoseconds spent executing 70 JDBC batches;
    0 nanoseconds spent performing 0 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    18845894086 nanoseconds spent executing 39 flushes (flushing a total of 388757 entities and 0 collections);
    0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}

我遗漏了一些无法正确执行批量插入/更新的内容。

postgresql spring-boot spring-data-jpa
1个回答
0
投票

考虑以下方法:

  1. 将主键生成策略更改为GenerationType.SEQUENCE。如果我们的实体使用 GenerationType.IDENTITY 标识符生成器,Hibernate 将默默地禁用批量插入。
  2. 将 hibernate.jdbc.batch_versioned_data 设置为 true。如果您使用的是 3.x 和 4.x 版本,这允许 Hibernate 即使使用自动生成的 ID 也可以批量插入

参考资料: https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/batch/Batching.html

© www.soinside.com 2019 - 2024. All rights reserved.