我看到有的数据库是一万条数据和八万条数据还有十几万条,几百万的数据,然后我就想拿这些数据测试一下,发现如果用java和数据库查询就连一万多条的数据查询出来就要10s左右,感觉太慢了。然后网上都说各种加索引,加索引貌似是有查询条件时在某个字段加索引比较快一些,但是毕竟是人家的库不能瞎动,再者说了,数据量偏大一点的,条件加上也还有好多数据怎么办,我想到了多线程的方式,话不多说,开始弄

多线程有好几种方式,今天说的方式比较好,实现Callable<> 这种方式能返回查询的数据,加上Future异步获取方式,查询效率大大加快

线程类

  1. package com.ThreadPoolHadel;
  2. import com.sqlSource.SqlHadle;
  3. import java.util.List;
  4. import java.util.concurrent.Callable;
  5. /**
  6. * Created by df on 2018/9/20.
  7. */
  8. public class ThredQuery implements Callable<List> {
  9. SqlHadle sqlHadle=new SqlHadle();
  10. private String search;//查询条件 根据条件来定义该类的属性
  11. private int bindex;//当前页数
  12. private int num;//每页查询多少条
  13. private String table;//要查询的表名,也可以写死,也可以从前面传
  14. private List page;//每次分页查出来的数据
  15. public ThredQuery(int bindex,int num,String table) {
  16. this.bindex=bindex;
  17. this.num=num;
  18. this.table=table;
  19. //分页查询数据库数据
  20. page=sqlHadle.queryTest11(bindex,num,table);
  21. }
  22. @Override
  23. public List call() throws Exception {
  24. //返回数据给Future
  25. return page;
  26. }
  27. }

调用类

  1. package com.service;
  2. import com.ThreadPoolHadel.ThredQuery;
  3. import com.sqlSource.SqlHadle;
  4. import org.springframework.stereotype.Service;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import java.util.concurrent.*;
  8. /**
  9. * Created by df on 2018/9/20.
  10. */
  11. @Service
  12. public class TheardQueryService {
  13. SqlHadle sqlHadle=new SqlHadle();
  14. public List<List> getMaxResult(String table) throws InterruptedException, ExecutionException {
  15. long start = System.currentTimeMillis();//开始时间
  16. List<List> result = new ArrayList<>();//返回结果
  17. //查询数据库总数量
  18. int count = sqlHadle.count(table);
  19. int num = 8000;//一次查询多少条
  20. //需要查询的次数
  21. int times = count / num;
  22. if (count % num != 0) {
  23. times = times + 1;
  24. }
  25. //开始页数 连接的是orcle的数据库 封装的分页方式 我的是从1开始
  26. int bindex = 1;
  27. //Callable用于产生结果
  28. List<Callable<List>> tasks = new ArrayList<>();
  29. for (int i = 0; i < times; i++) {
  30. Callable<List> qfe = new ThredQuery(bindex, num, table);
  31. tasks.add(qfe);
  32. bindex += bindex;
  33. }
  34. //定义固定长度的线程池 防止线程过多
  35. ExecutorService executorService = Executors.newFixedThreadPool(15);
  36. //Future用于获取结果
  37. List<Future<List>> futures=executorService.invokeAll(tasks);
  38. //处理线程返回结果
  39. if(futures!=null&&futures.size()>0){
  40. for (Future<List> future:futures){
  41. result.addAll(future.get());
  42. }
  43. }
  44. executorService.shutdown();//关闭线程池
  45. long end = System.currentTimeMillis();
  46. System.out.println("线程查询数据用时:"+(end-start)+"ms");
  47. return result;
  48. }
  49. }

19600多条数据3秒内查询完,对于之前10m查询完毕,已经提高很多的效率了
17. java用多线程批次查询大量数据(Callable返回数据)方式 - 图1
80000多条数据7m就完成了
17. java用多线程批次查询大量数据(Callable返回数据)方式 - 图2
830305万的数据需要40m ,哈哈哈,也算差不多一百万的数据了,最主要的是没有卡死,好像不经过处理很容易卡死
17. java用多线程批次查询大量数据(Callable返回数据)方式 - 图3

5184121万的数据报GC了,那就演示到这吧,五百万的数据实在不适合这样查

最主要的是,你的数据量大的话要相应的更改调用方法里的 num,一次性多查点,效率会高很多

转载 https://blog.csdn.net/dfBeautifulLive/article/details/82788830