我设计过数据库,也写过很多业务代码。我们设计数据库的时候,一般都是外键关联,每次需要外键涉及到的表的属性,都是直接关联查询或者用到的时候再去查询。原来没有分库分表,一个sql搞定。现在分库分表之后,发现每次都得二次查询。这样就需要针对查询出来的list再重新封装一次。
我们大家很熟悉的,都不用思考的就是这样写,至少我从来没测试过这样写的效率,
for(int i = 0;i<userInfoList.size;i++) { //for(UserInfo eachUserInfo:userInfoList)
UserInfo eachUserInfo = userInfoList.get(i);
UserInfoView userInfoView = new UserInfoView();
userInfoView.setId(eachUserInfo.getId());
userInfoView.setName(eachUserInfo.getName());
userInfoView.setCarId(eachUserInfo.getCarId());
userInfoView.setCarDesc(userInfoDao.queryCar(eachUserInfo.getCarId()));
userInfoViewList.add(userInfoView);
});
今天看到一篇文章,让我大开眼界。于是测试了几种方法,发现效率真的很有差别。
先说一个线程执行到底,
- for(int i = 0;i<userInfoList.size;i++) {
- for(UserInfo eachUserInfo:userInfoList)
- userInfoList.foreach((eachUserInfo)->{}); //jdk1.8后引入
- userInfoList.stream().map(()->{}).collect(Collectors.toList());//jdk1.8后引入
我用600条数据做的测试,以上几种方式,都是需要3分钟左右。
然后改成多线程执行,
- 用Executors框架
ExecutorService executorService = Executors.newCachedThreadPool();
Future<String> getJobDesc = executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return userInfoDao.queryJob(userInfo.getJobId());
}
});
但是也用了3分钟左右
- 用new Thread(),我是这么理解的,因为不能接受Callable类型的参数,所以借用了FutureTask
FutureTask<String> getJobDesc = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
return userInfoDao.queryJob(userInfo.getJobId());
}
});
new Thread(getJobDesc).start();
只用了1分钟。
- 用CompletableFuture,
private Supplier<UserInfoDao> queryUtilsSupplier = UserInfoDao::new;
CompletableFuture<UserInfoDao> getJobDesc = CompletableFuture.supplyAsync(queryUtilsSupplier);
getJobDesc.thenAccept(new Consumer<UserInfoDao>() {
@Override
public void accept(UserInfoDao userInfoDao) {
userInfoView.setJobDesc(userInfoDao.queryJob(userInfo.getJobId()));
}
});
也用了1分钟左右。
请问我们是否有必要改成FutureTask或者CompletableFuture,还是得考虑一下。

本文探讨了在数据库分库分表后,如何优化大量数据的查询效率。通过对比不同编程方法,如线程执行、多线程、FutureTask及CompletableFuture,实测显示多线程与异步处理能显著提升查询速度。
220

被折叠的 条评论
为什么被折叠?



