java解决mysql大数据联查问题

java解决mysql大数据联查问题

近期有一个需求是联查两张表比对三个字段
一般用mysql就可以解决

SELECT
	* 
FROM
	tb_a a
	LEFT JOIN b ON a.test = b.test
	AND a.NAME = b.NAME 
	AND a.type = b.type

但是表a和表b的数据量都很不小,大概在10w左右,由于并不是以固定的id去关联,加了索引也没有效果,使用navicate根本就查不出来。
这时候想到了使用java去查,一开始采用的是双重for去比对,但是导致内存溢出根本差不出来。
后来想到了使用map利用这三个字段作为key去查,查询结果很快,大概几秒内就查出来了,由于这次是一个数据比对导出,不涉及到上线业务,所以就没有进行进一步的优化。
下面是核心代码

 public List<NoWidCompareDTO> getNoWidCompare() {
        List<NoWidCompareDTO> result = new ArrayList<>();
       
        // 为了方便直接查的,可以优化查询
        List<EEaResourceDataWidNo> noWidList = noWidMapper.selectList(null);
        List<CollectionAllLevel> otherList = allLevelMapper.selectList(null);
        log.info("开始比对:{}", DateUtil.now());

        // 构建一个以三个条件为键,CollectionAllLevel对象为值的Map,方便后续查找
        Map<String, CollectionAllLevel> otherMap = new HashMap<>();
        for (CollectionAllLevel allLevelDTO : otherList) {
            String key = getKey(allLevelDTO);
            otherMap.put(key, allLevelDTO);
        }

        for (EEaResourceDataWidNo noWidDTO : noWidList) {
            String key = getKey(noWidDTO);
            CollectionAllLevel allLevelDTO = otherMap.get(key);
            // 构建NoWidCompareDTO,并进行属性复制
            NoWidCompareDTO dto = BeanUtil.toBean(noWidDTO, NoWidCompareDTO.class);
            if (allLevelDTO != null) {
                // 如果比对成功进行复制
                BeanUtil.copyProperties(allLevelDTO, dto);
            }
            // 都要添加进去
            result.add(dto);
        }

        log.info("比对结束:{}", DateUtil.now());
        return result;
    }
    
   /**
     * 等级,馆藏名称,资源名称统一设置为key,当然也可以在查询的时候直接设置
     */
    private String getKey(EEaResourceDataWidNo noWidDTO) {
        return noWidDTO.getLevel() + "_" + noWidDTO.getCollectionUnits() + "_" + noWidDTO.getResourceName();
    }

    /**
     * 等级,馆藏名称,资源名称统一设置为key,当然也可以在查询的时候直接设置
     */
    private String getKey(CollectionAllLevel allLevelDTO) {
        return allLevelDTO.getOtherLevel() + "_" + allLevelDTO.getMuseumCollectionName() + "_" + allLevelDTO.getCollectionName();
    }

这效果和以a表作为主表进行左连接查询一样。
总之上面的代码仅作为简单的操作,还有一些逻辑都没校验,也可以进行优化,重点就是使用map的key,value进行操作比对

你可能感兴趣的:(java,mysql,大数据)