java-40万数据迁移之路

听朋友一个需求,根据A库的t1表数据修改B库t2表的数据,有唯一对应关系。

直接采用java代码一条一条去update,一段程序的优化之路。

最初代码如下:

 

java-40万数据迁移之路_第1张图片

程序执行10条发现没问题,开始执行100条,发现太慢了。感觉串行去修改效率不高,考虑多线程。直接上多线程代码

java-40万数据迁移之路_第2张图片

emmmm 是多线程,也有shutdown,代码codeview无误。执行结果太慢了。然后想看看是不是多线程,打印了执行线程id,结果发现怎么是串行的。

原来执行还是单线程,代码位置有误,for循环应该放道提交任务的外面,继续修改

java-40万数据迁移之路_第3张图片

打印结果是多线程,happy,解决了。执行300条数据,执行时间居然3分钟,一分钟更新100条,40万需要……

 

再看也看不出有什么需要修改的地方,想想修改mysql的连接数据,修改线程池数量大小,修改内容添加索引,结果没有任何变化。

看到update想到为什么要先查询在去修改呢。于是去掉查询,执行300条瞬间完成。哇……查询这么耗时。

 

优化思路:

1、能并行处理任务就不要串行处理

2、添加索引,修改程序连接数据的连接数

3、扩大线程池大小

4、去掉不必要的查询,减少和数据库交互

 

最终代码如下:

public void executor(){
        int pageSize = 8000;
        int pageIndex = 1;
        while (true) {
            int start = (pageIndex - 1) * pageSize;
            final List resultsList = resultsDaoMapper.limit(start,pageSize );
            if (CollectionUtils.isEmpty(resultsList)){
                return;
            }


            final ExecutorService executorService = Executors.newFixedThreadPool(1000);
            for (Results results: resultsList){
                executorService.submit(new Runnable() {
                    @Override public void run() {
                        UserPo userPo = new UserPo();
                        try{
                            userPo.setPhone(results.getUsername())
                            userPo.setSalt(results.getSalt());
                            userDaoMapper.update(userPo);
                        }catch(Exception e){
                        //results.getUsername()输出
                        }
                    }
                });
            }
            executorService.shutdown();
            try {
                executorService.awaitTermination(10, TimeUnit.MINUTES);
            } catch (InterruptedException e) {
            }
        }
//结束
    }

 

你可能感兴趣的:(多线程,结构优化,数据迁移)