excel导入数据并比对存入数据库

我数据库现在有5w条数据 每次从Excel导入200条 ,我数据库表有一个 detail 字段  每次导入都需要判断 detail 字段与全部数据的detail 字段的相似度,超过百分之八十 就给这条数据的 state字段赋值为1 否则就赋值0  我用stream流还是太慢, 怎么优化

下面是我写的

@Service
@Transactional
public class fileServiceImpl implements fileService {
    //相似度阈值
    private static final double SIMILARITY = 0.8;

    @Autowired
    private WorkDtlDao workDtlDao;

    @Autowired
    private WorkTeamDao workTeamDao;

    /**
     * @param dailyImports excel导入的数据
     * @param beginDate    前端传的开始时间
     * @param endDate      结束时间
     * @param week         第几周
     */
    @Override
    public void importFrom2Time(List<WorkDtl> dailyImports, String beginDate, String endDate, String week) {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");

        //一次查询 减少数据库io 废内存
        CopyOnWriteArrayList<String> strings = workDtlDao.selectByGsDetail();
        //迭代器 伪多线程
        dailyImports.forEach(e -> {
            e.setWeek(week);
            e.setBeginDate(format.format(new Date(Long.parseLong(beginDate))));
            e.setEndDate(format.format(new Date(Long.parseLong(endDate))));
            e.setUid(UUID.randomUUID().toString());
            e.setState(0);
//            AtomicReference<Double> num = new AtomicReference<>(0.0);
//            strings.forEach(es -> {
//
//            });
            //设置标准可以提前跳出for循环
            double num = 0.0;
            for (String es : strings) {
                num = TextSimilarity.sim(es, e.getGsDetail());
//                num.set(sim > num.get() ? sim : num.get());
                if (num > SIMILARITY) {
                    break;
                }
            }
            e.setState(num >= SIMILARITY ? 1 : 0);
            workDtlDao.insert(e);
            //把信曾的数据加到list中,不需要再次查询数据库,减少io
//            if (e.getState().equals(0))
            strings.add(e.getGsDetail());
        });


    }

 

这个例子中,用批量写的方式会比用多线程有更好的优化效果。
如果非要用多线程的话,有两种解决方法:
1.(推荐)使用生产者消费者模型,将处理好的数据写到一个线程安全的队列中,用消费者读取这个队列并批量写入数据库
2.(不推荐)用stream的parallel方法,将流变为并发的  https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html

我看你46行代码是单条插入把,可以考虑将结果存到一个list中,然后批量插入。

导入是非常费数据库性能的,你每次一条一条导入,边导入边比较,是非常慢的,你现在还是40几条,等你几万条的时候,不得等个十几分钟?所以这种解决方案就是,先全部一次性导入,可以利用数据的批量插入,然后导入成功后,然后处理相似的,不管是删除条,还是改状态

您好,我是问答小助手,你的问题已经有小伙伴为您解答了问题,您看下是否解决了您的问题。

如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~