求助, java查询优化

才3w数据, 做一张多对多的数据表去关联查都比直接加redis好. 不要慌!

1 个赞

3w还是查出来 放到内存处理吧 之前在mybatis里递归查 卡的要死 优化后直接提速100倍

1 个赞

那肯定的

redis+数据库的一致性问题,无非就是前删、后删、双删,高级一点还可以整整canal这些,但是我的建议是数据量不大直接从数据库里面取就行了,遇到性能问题的时候再考虑优化,不然事情都做完了后面做什么

1 个赞

之前我同事也遇到过这个问题 我们是单层数据用父子关系组成一棵树 用广度优先遍历去做比纯递归性能好点 不知道能不能给你提供帮助 很久之前写的了 说实话今天不是看到你这个帖子 我都已经快忘记了 如果已经解决了 也请分享一下解决思路哈哈



@Data
@AllArgsConstructor
public class AuthCorpDeptUserRelationDTO {

    private String deptId;

    private String userid;
}




@Data
@AllArgsConstructor
public class CorpTreeDTO {
    private String deptId;

    private String departmentId;

    private String parentId;

    private List<CorpTreeDTO> corpTreeDTOList;

    private List<String> userList;
}


@Data
@AllArgsConstructor
public class CustomerDTO {
    private String name;
    private String customerId;

    private String customerParentId;

    private List<CustomerDTO> childList;
}



  private static List<CustomerDTO> getTree(){
        List<CustomerDTO> res = new ArrayList<>();
        List<CustomerDTO> customerDTOS = new ArrayList<>();
        for(int i = 0; i < 10000; i++){
            customerDTOS.add(new CustomerDTO("测试",String.valueOf(i) , null, null));
        }
        for (int i = 10000; i < 20000; i++){
            customerDTOS.add(new CustomerDTO("测试",String.valueOf(i) , String.valueOf(i - 10000), null));
        }
        for (int i = 20000; i < 30000; i++){
            customerDTOS.add(new CustomerDTO("测试",String.valueOf(i) , String.valueOf(i - 10000), null));
        }
        for (int i = 30000; i < 40000; i++){
            customerDTOS.add(new CustomerDTO("测试",String.valueOf(i) , String.valueOf(i - 10000), null));
        }
        for (int i = 40000; i < 50000; i++){
            customerDTOS.add(new CustomerDTO("测试",String.valueOf(i) , String.valueOf(i - 10000), null));
        }
        for (int i = 50000; i < 60000; i++){
            customerDTOS.add(new CustomerDTO("测试",String.valueOf(i) , String.valueOf(i - 10000), null));
        }


        //递归实现构建树
        long time3 = System.currentTimeMillis();
        List<CustomerDTO> resultList = new ArrayList<>();
        for (int i = 0; i < customerDTOS.size();i++){
            if (StringUtils.isEmpty(customerDTOS.get(i).getCustomerParentId())){
                resultList.add(customerDTOS.get(i));
            }
        }
        findParent(resultList, customerDTOS);


        long time4 = System.currentTimeMillis();
//        System.out.println(JSONObject.toJSONString(resultList));

        //队列实现构建树
        long time1 = System.currentTimeMillis();
        Queue<CustomerDTO> indexQueue = new ArrayDeque<>();
        Queue<CustomerDTO> childQueue = new ArrayDeque<>();

        for (int i = 0 ; i < customerDTOS.size(); i++){
            customerDTOS.get(i).setChildList(new ArrayList<>());
            if (StringUtils.isEmpty(customerDTOS.get(i).getCustomerParentId())) {
                indexQueue.add(customerDTOS.get(i));
                res.add(customerDTOS.get(i));
            }else {
                childQueue.add(customerDTOS.get(i));
            }
        }
        while(indexQueue.peek() != null && childQueue.size() > 0){
            CustomerDTO poll = indexQueue.poll();
            int size = childQueue.size();
            for(int i = 0; i < size; i++){
                CustomerDTO childPoll = childQueue.poll();
                if (poll.getCustomerId().equals(childPoll.getCustomerParentId())){
                    poll.getChildList().add(childPoll);
                    indexQueue.add(childPoll);
                }else{
                    childQueue.add(childPoll);
                }
            }
        }
        long time2 = System.currentTimeMillis();
//        System.out.println(JSONObject.toJSONString(res));
        System.out.println("递归构建: " + (time4 - time3) + "ms");
        System.out.println("队列构建: " + (time2 - time1) + "ms");
        return res;
    }


    private static List<CorpTreeDTO> getListTree(){
        List<CorpTreeDTO> mapperList = new ArrayList<>();
        List<CorpTreeDTO> resList = new ArrayList<>();
        List<AuthCorpDeptUserRelationDTO> userMapperList = new ArrayList<>();
        Queue<CorpTreeDTO> indexQueue = new ArrayDeque<>();
        Queue<CorpTreeDTO> childQueue = new ArrayDeque<>();
        Queue<AuthCorpDeptUserRelationDTO> userQueue = new ArrayDeque<>();

        //初始化数据
        for (int i = 0; i < 100; i++){
            mapperList.add(new CorpTreeDTO(String.valueOf(i),"","",null,null));
        }
        for(int j = 1; j < 40; j++){
            for (int i = j * 100; i < j * 200; i++){
                mapperList.add(new CorpTreeDTO(String.valueOf(i*j),"",String.valueOf(i - j * 100),null,null));
            }
        }

        for (int i = 0; i < 600; i++){
            for (int j = 0; j < 10; j++){
                userMapperList.add(new AuthCorpDeptUserRelationDTO(String.valueOf(i), "userId" + j));
            }
        }

        long time1 = System.currentTimeMillis();
        mapperList.forEach(mapper ->{
            mapper.setCorpTreeDTOList(new ArrayList<>());
            mapper.setUserList(new ArrayList<>());
            if (StringUtils.isEmpty(mapper.getParentId())){
                indexQueue.add(mapper);
                resList.add(mapper);
            }else {
                childQueue.add(mapper);
            }
        });
        userMapperList.forEach(userMapper ->{
            userQueue.add(userMapper);
        });

        while(indexQueue.peek() != null && childQueue.size() > 0){
            CorpTreeDTO poll = indexQueue.poll();
            int userQueueSize = userQueue.size();
            for (int i = 0; i < userQueueSize; i++){
                AuthCorpDeptUserRelationDTO relationPoll = userQueue.poll();
                if (relationPoll.getDeptId().equals(poll.getDeptId())){
                    poll.getUserList().add(relationPoll.getUserid());
                }else {
                    userQueue.add(relationPoll);
                }
            }
            int size = childQueue.size();
            for(int i = 0; i < size; i++){
                CorpTreeDTO childPoll = childQueue.poll();
                if (childPoll.getParentId().equals(poll.getDeptId())){
                    poll.getCorpTreeDTOList().add(childPoll);
                    indexQueue.add(childPoll);
                }else{
                    childQueue.add(childPoll);
                }
            }
        }
        long time2 = System.currentTimeMillis();
//        System.out.println(JSONObject.toJSONString(resList));
        System.out.println("构建tree: " + (time2 - time1) + "ms");
        return resList;
    }

    private static void findParent(List<CustomerDTO> resultList, List<CustomerDTO> customerDTOS){
        for(int i = 0; i < resultList.size(); i++){
            resultList.get(i).setChildList(new ArrayList<>());
            for (int j = 0; j < customerDTOS.size(); j++){
                if (!StringUtils.isEmpty(customerDTOS.get(j).getCustomerParentId()) && customerDTOS.get(j).getCustomerParentId().equals(resultList.get(i).getCustomerId())){
                    resultList.get(i).getChildList().add(customerDTOS.get(j));
                }
            }
            findParent(resultList.get(i).getChildList(), customerDTOS);
        }
    }

    public static void main(String[] args) {
        getTree();
        getListTree();
    }
1 个赞

3w数据你真的是大海里涮拖把了,sql就可以了,不想频繁的执行sql语句可以在orm框架中加上缓存的

1 个赞

3W…直接放内存里也没多少吧

1 个赞

直接数据库查,感觉会更快,毕竟你要有更新redis的操作,脱裤子放屁,直接查数据库,重新梳理设计按照层级设计几个表,搞好主键和索引,3万数据,不会慢多少的

1 个赞

我好奇的是 为什么要把这个操作拿到代理商登录账号的时候做?代理商通过什么渠道知道是否他的用户结构发生变化?

1 个赞

3w数据,查询慢,不是很理解

1 个赞

3w这个数量应该还好吧,我寻思这个量是不是连redis都不用了

你需要具体分析下慢的原因,是数据库还是代码

1 个赞

此话题已在最后回复的 30 天后被自动关闭。不再允许新回复。