场景是这样的:使用in查询数据的时候,in的数量越多,效率越低,所以一个优化的思路是,缩小in查询的数量,用多线程的方式查询缩小数量后in的sql,并行查询。
直接上代码:
- public List
getCscpOrgInfoByUserId(List userIds) { -
- //List
list = innerWorkFlowRepository.batchGetCscpOrgInfoByUserId(userIds); - List
list = getInListThread(userIds); - return list;
- }
-
- private List
getInListThread(List userIds) { - List
resultList = Collections.synchronizedList(new ArrayList<>()); - List
tasks = new ArrayList<>(); - int threshold = 3; // 每个线程最大条数
- int threadNum = userIds.size() / threshold; // 线程个数
- int lastSize = userIds.size() % threshold; // 最后一个线程的数据条数
- //多线程
- for (int i = 0; i <= threadNum; i++) {
- int start = i * threshold;
- int end = 0;
- if (i != threadNum) {
- end = (i + 1) * threshold;
- } else {
- end = lastSize == 0 ? start : (lastSize + start);
- }
- int finalEnd = end;
- CompletableFuture
task = CompletableFuture.runAsync(() -> { - List
tempMsIdList = new ArrayList<>(); - for (int j = start; j < finalEnd; j++) {
- tempMsIdList.add(userIds.get(j));
- }
- List
temps = new ArrayList<>(); - if(!org.springframework.util.CollectionUtils.isEmpty(tempMsIdList)){
- //查询SQL
- System.out.println(Thread.currentThread().getId() + "in的数量:" + tempMsIdList.size());
- temps = innerWorkFlowRepository.batchGetCscpOrgInfoByUserId(tempMsIdList);
- }
- if (!org.springframework.util.CollectionUtils.isEmpty(temps)) {
- resultList.addAll(temps);
- }
- });
- tasks.add(task);
- }
- CompletableFuture.allOf(tasks.toArray((new CompletableFuture[] {}))).join();
-
- return resultList;
- }
其中,只需配置private的方法中的最大线程数参数threshold即可,按照实际需求配置,此时我配置的参数是3,即每次in的数量是3个,测试userIds的数量是8个。
打印的结果如下(sql日志忽略):