Spring Batch结合Hibernate写入Azure SQL Server性能过低如何优化
性能优化方案
以下是可直接落地的优化措施,按优先级从高到低排列:
- 修正ItemWriter实现,充分利用块处理能力
现有StoreWriter的写法完全浪费了Spring Batch的块(Chunk)处理特性,需要将多层嵌套的列表展开后一次性提交给HibernateItemWriter,减少重复调用开销:
@Override public void write(List<? extends List<Store>> items) throws Exception { List<Store> allStores = items.stream() .flatMap(List::stream) .toList(); hibernateItemWriter.write(allStores); logger.info(String.format("Store Processing Completed %s", LocalDateTime.now())); }
同时调大Step的Chunk大小,建议设置为50~200,和后续的Hibernate批量参数匹配。
- 补充Hibernate批量写入配置
现有Hibernate配置未开启JDBC批量优化,需要在hibernateProperties中新增以下参数:
<prop key="hibernate.jdbc.batch_size">100</prop> <prop key="hibernate.order_inserts">true</prop> <prop key="hibernate.order_updates">true</prop> <prop key="hibernate.jdbc.batch_versioned_data">true</prop>
开启后Hibernate会自动将同类型实体的插入/更新操作合并为批量SQL,大幅降低和数据库的交互次数。
- 替换无连接池的数据源
当前使用的DriverManagerDataSource没有连接池能力,每次数据库操作都会新建连接,开销极高,建议替换为HikariCP连接池,配置示例:
<bean id="demoDataSource" class="com.zaxxer.hikari.HikariDataSource"> <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> <property name="jdbcUrl" value="jdbc:sqlserver://demo.database.windows.net:1433;database=sqldb;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;sendStringParametersAsUnicode=false;" /> <property name="username" value="user1" /> <property name="password" value="p@ssword1" /> <property name="maximumPoolSize" value="20" /> <property name="minimumIdle" value="5" /> </bean>
连接字符串新增的sendStringParametersAsUnicode=false参数可以减少SQL Server的参数转换开销,提升批量写入性能。
- Azure SQL侧优化
- 检查Azure SQL的服务层级,若当前使用低配置的基础/标准层,可临时提升vCore规格测试吞吐量
- 若为全量导入场景,可先禁用目标表的非主键索引,导入完成后再重建,减少索引维护开销
- 若写入逻辑非常简单,可直接替换
HibernateItemWriter为JdbcBatchItemWriter,去掉ORM层开销,性能可提升30%以上
- 并行处理提升吞吐量
如果业务允许数据无序处理,可给Step配置多线程执行器,或使用分区器拆分CSV文件并行处理,吞吐量可随线程数线性提升。
原始运行统计数据
- 单条记录处理统计

- 3条记录处理统计

内容的提问来源于stack exchange,提问作者One Developer
相关产品推荐
相关产品推荐

