做企业网站多少钱网站建设制作ppt
2026/2/6 5:32:11 网站建设 项目流程
做企业网站多少钱,网站建设制作ppt,观山湖网站建设推广,网页设计公司企业文化上周接了个数据迁移的活#xff0c;要把10万条数据从老系统导入新系统。 写了个简单的批量插入#xff0c;跑起来一看——5分钟。 领导说太慢了#xff0c;能不能快点#xff1f; 折腾了一下午#xff0c;最后优化到3秒#xff0c;记录一下过程。最初的代码#xff08;5…上周接了个数据迁移的活要把10万条数据从老系统导入新系统。写了个简单的批量插入跑起来一看——5分钟。领导说太慢了能不能快点折腾了一下午最后优化到3秒记录一下过程。最初的代码5分钟最开始写的很简单foreach循环插入// 方式1循环单条插入最慢for(Useruser:userList){userMapper.insert(user);}10万条数据每条都要走一次网络请求、一次SQL解析、一次事务提交。算一下假设每条插入需要3ms10万条就是300秒 5分钟。这是最蠢的写法但我见过很多项目都这么写。第一次优化批量SQL30秒把循环插入改成批量SQL!-- Mapper.xml --insertidbatchInsertINSERT INTO user (name, age, email) VALUESforeachcollectionlistitemitemseparator,(#{item.name}, #{item.age}, #{item.email})/foreach/insert// 分批插入每批1000条intbatchSize1000;for(inti0;iuserList.size();ibatchSize){intendMath.min(ibatchSize,userList.size());ListUserbatchuserList.subList(i,end);userMapper.batchInsert(batch);}从5分钟降到30秒提升10倍。原理一条SQL插入多条数据减少网络往返次数。但还有问题30秒还是太慢。第二次优化JDBC批处理8秒MySQL有个参数叫rewriteBatchedStatements开启后可以把多条INSERT合并成一条。第一步修改数据库连接URLjdbc:mysql://localhost:3306/test?rewriteBatchedStatementstrue第二步使用MyBatis的批处理模式AutowiredprivateSqlSessionFactorysqlSessionFactory;publicvoidbatchInsertWithExecutor(ListUseruserList){try(SqlSessionsqlSessionsqlSessionFactory.openSession(ExecutorType.BATCH)){UserMappermappersqlSession.getMapper(UserMapper.class);intbatchSize1000;for(inti0;iuserList.size();i){mapper.insert(userList.get(i));if((i1)%batchSize0){sqlSession.flushStatements();sqlSession.clearCache();}}sqlSession.flushStatements();sqlSession.commit();}}从30秒降到8秒。原理ExecutorType.BATCH模式下MyBatis会缓存SQL最后一次性发送给数据库执行。配合rewriteBatchedStatementstrueMySQL驱动会把多条INSERT合并。第三次优化多线程并行3秒8秒还是不够快上多线程publicvoidparallelBatchInsert(ListUseruserList){intthreadCount4;// 根据数据库连接池大小调整intbatchSizeuserList.size()/threadCount;ExecutorServiceexecutorExecutors.newFixedThreadPool(threadCount);ListFuture?futuresnewArrayList();for(inti0;ithreadCount;i){intstarti*batchSize;intend(ithreadCount-1)?userList.size():(i1)*batchSize;ListUsersubListuserList.subList(start,end);futures.add(executor.submit(()-{batchInsertWithExecutor(subList);}));}// 等待所有任务完成for(Future?future:futures){try{future.get();}catch(Exceptione){thrownewRuntimeException(e);}}executor.shutdown();}从8秒降到3秒。注意事项线程数不要超过数据库连接池大小如果需要事务一致性这个方案不适用要考虑主键冲突的问题优化效果对比方案耗时提升倍数循环单条插入300秒基准批量SQL30秒10倍JDBC批处理8秒37倍多线程并行3秒100倍踩过的坑坑1foreach拼接SQL过长foreachcollectionlistitemitemseparator,如果一次插入太多条SQL会非常长可能超过max_allowed_packet限制。解决分批插入每批500-1000条。坑2rewriteBatchedStatements不生效检查几个点URL参数是否正确rewriteBatchedStatementstrue是否使用了ExecutorType.BATCHMySQL驱动版本是否太旧坑3自增主键返回问题批量插入时想获取自增主键insertidbatchInsertuseGeneratedKeystruekeyPropertyid注意rewriteBatchedStatementstrue时自增主键返回可能有问题需要升级MySQL驱动到8.0.17。坑4内存溢出10万条数据一次性加载到内存可能OOM。解决分页读取 分批插入。intpageSize10000;inttotalcountTotal();for(inti0;itotal;ipageSize){ListUserpageselectByPage(i,pageSize);batchInsertWithExecutor(page);}最终方案代码ServicepublicclassBatchInsertService{AutowiredprivateSqlSessionFactorysqlSessionFactory;/** * 高性能批量插入 * 10万条数据约3秒 */publicvoidhighPerformanceBatchInsert(ListUseruserList){if(userListnull||userList.isEmpty()){return;}intthreadCountMath.min(4,Runtime.getRuntime().availableProcessors());intbatchSize(int)Math.ceil((double)userList.size()/threadCount);ExecutorServiceexecutorExecutors.newFixedThreadPool(threadCount);CountDownLatchlatchnewCountDownLatch(threadCount);for(inti0;ithreadCount;i){intstarti*batchSize;intendMath.min((i1)*batchSize,userList.size());if(startuserList.size()){latch.countDown();continue;}ListUsersubListnewArrayList(userList.subList(start,end));executor.submit(()-{try{doBatchInsert(subList);}finally{latch.countDown();}});}try{latch.await();}catch(InterruptedExceptione){Thread.currentThread().interrupt();}executor.shutdown();}privatevoiddoBatchInsert(ListUseruserList){try(SqlSessionsqlSessionsqlSessionFactory.openSession(ExecutorType.BATCH,false)){UserMappermappersqlSession.getMapper(UserMapper.class);for(inti0;iuserList.size();i){mapper.insert(userList.get(i));if((i1)%10000){sqlSession.flushStatements();sqlSession.clearCache();}}sqlSession.flushStatements();sqlSession.commit();}}}总结优化点关键配置批量SQLforeach拼接分批1000条JDBC批处理rewriteBatchedStatementstrueExecutorType.BATCH多线程线程数 ≤ 连接池大小核心原则减少网络往返 减少事务次数 并行处理。有其他批量操作的优化经验欢迎评论区交流~

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询