我通过将MyBatis中的变量List传递给Oracle DB来更新大量数据。
还不够高效,逐行提交更新sql查询,在sql查询或Executor.batch服务中进行循环的方式与我期望的相比太慢了。
//one of the method i use <update id="updateAll"> BEGIN <foreach collection="list" item="item" index="index" separator=";"> UPDATE <include refid="tableName"/> <set> item_price = ${item.price}, update_time = ${item.updateTime} </set> WHERE id = ${item.id} </foreach> ;END; </update>
通过尝试的方式,我的系统花费了10到30秒甚至更长的时间来完成更新。服务器每秒将有大约10,000行数据。有什么方法可以在1或2秒内在Oracledb中更新至少1-2k数据行?
建议使用批处理执行器,但是您需要正确执行。 我注意到了两个问题。
${}
#{}``${}
这是使用MyBatis的典型批处理操作。 由于最好batchSize取决于各种因素,因此应使用实际数据来衡量性能。
batchSize
int batchSize = 1000; try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) { YourMapper mapper = sqlSession.getMapper(YourMapper.class); int size = list.size(); for (int i = 0; i < size;) { mapper.update(list.get(i)); i++; if (i % batchSize == 0 || i == size) { sqlSession.flushStatements(); sqlSession.clearCache(); } } sqlSession.commit(); }
这是update语句的有效版本。
<update id="update"> UPDATE <include refid="tableName" /> SET item_price = #{item.price}, update_time = #{item.updateTime} WHERE id = #{item.id} </update>