场景是这样的:使用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)){//查询SQLSystem.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日志忽略):
