如何在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

回到顶部