如何在spring中使用多线程完成分页接口的两次查询数据库?
通常情况下,分页接口一般会查询两次数据库,第一次是获取具体数据,第二次是获取总的记录行数,然后把结果整合之后,再返回。
例如:
select id,name from user limit 20; // 查询数据
select count(*) from user; // 查询数量
现在count(*) 查询数据效率很慢,想使用spring多线程完成性能优化,如何实现?
回答:
SELECT SQL_CALC_FOUND_ROWS * from user; SELECT FOUND_ROWS()
回答:
像mybatis的话,你就得自己去改造插件去做异步了,说难不难,说易不易吧
回答:
count()很慢 你用多线程最快也就跟count()的速度一样啊 解决不了问题
应该从sql角度优化下或者加缓存来解决
回答:
count() 理论上只要索引合理,是没太多方案在sql数据库索引层面解决问题了而且使用count(),还特别慢的话,如果业务对总数不敏感的话,你可以考虑使用redis,对count(*)的结果进行缓存可以隔一两个小时失效同步一次数据,这样做虽然数据会出现延迟不过会在可接受范围内。如果要求敏感的话,你可以进行增量处理,先缓存数据库数据,然后没增加一个数据,就更新redis缓存,这样做的话,就算更新频繁也只会出现少量的用户量偏差,不特别影响数据观测
回答:
分页查询,必须知道总数才能进行分页。所以必须根据count()的结果来进行分页。
所以不可能通过异步的方式来实现这个业务,通常的做法都是通过优化sql来提升查询速度。
回答:
MyBatis-Plus版:
使用示例:
demoService.pageParallel(new Page<>(1, 10), Wrappers.lambdaQuery(DemoEntity.class));
代码实现:
private static final ExecutorService CACHED_THREAD_POOL_EXECUTOR = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("page-count-%d").build());@SneakyThrows
@Override
public <E extends IPage<T>> E pageParallel(E page, Wrapper<T> queryWrapper) {
CompletableFuture<Long> countFuture = CompletableFuture.supplyAsync(() -> count(queryWrapper), CACHED_THREAD_POOL_EXECUTOR);
page.setRecords(page(new Page<>(page.getCurrent(), page.getSize(), false), queryWrapper).getRecords());
page.setTotal(countFuture.get());
return page;
}
回答:
有create_date吗? 只差当天的数量, 当天以前的数量放redis里即可,
回答:
可以改成 count(id)
select count(id) from user; // 查询数量
本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。
以上是 如何在spring中使用多线程完成分页接口的两次查询数据库? 的全部内容, 来源链接: utcz.com/p/945064.html