我看到有的数据库是一万条数据和八万条数据还有十几万条,几百万的数据,然后我就想拿这些数据测试一下,发现如果用java和数据库查询就连一万多条的数据查询出来就要10s左右,感觉太慢了。然后网上都说各种加索引,加索引貌似是有查询条件时在某个字段加索引比较快一些,但是毕竟是人家的库不能瞎动,再者说了,数据量偏大一点的,条件加上也还有好多数据怎么办,我想到了多线程的方式,话不多说,开始弄
多线程有好几种方式,今天说的方式比较好,实现Callable<> 这种方式能返回查询的数据,加上Future异步获取方式,查询效率大大加快
线程类:
package com.ThreadPoolHadel;
import com.sqlSource.SqlHadle;
import java.util.List;
import java.util.concurrent.Callable;
/**
* Created by df on 2018/9/20.
*/
public class ThredQuery implements Callable<List> {
SqlHadle sqlHadle=new SqlHadle();
private String search;//查询条件 根据条件来定义该类的属性
private int bindex;//当前页数
private int num;//每页查询多少条
private String table;//要查询的表名,也可以写死,也可以从前面传
private List page;//每次分页查出来的数据
public ThredQuery(int bindex,int num,String table) {
this.bindex=bindex;
this.num=num;
this.table=table;
//分页查询数据库数据
page=sqlHadle.queryTest11(bindex,num,table);
}
@Override
public List call() throws Exception {
//返回数据给Future
return page;
}
}
调用类:
package com.service;
import com.ThreadPoolHadel.ThredQuery;
import com.sqlSource.SqlHadle;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* Created by df on 2018/9/20.
*/
@Service
public class TheardQueryService {
SqlHadle sqlHadle=new SqlHadle();
public List<List> getMaxResult(String table) throws InterruptedException, ExecutionException {
long start = System.currentTimeMillis();//开始时间
List<List> result = new ArrayList<>();//返回结果
//查询数据库总数量
int count = sqlHadle.count(table);
int num = 8000;//一次查询多少条
//需要查询的次数
int times = count / num;
if (count % num != 0) {
times = times + 1;
}
//开始页数 连接的是orcle的数据库 封装的分页方式 我的是从1开始
int bindex = 1;
//Callable用于产生结果
List<Callable<List>> tasks = new ArrayList<>();
for (int i = 0; i < times; i++) {
Callable<List> qfe = new ThredQuery(bindex, num, table);
tasks.add(qfe);
bindex += bindex;
}
//定义固定长度的线程池 防止线程过多
ExecutorService executorService = Executors.newFixedThreadPool(15);
//Future用于获取结果
List<Future<List>> futures=executorService.invokeAll(tasks);
//处理线程返回结果
if(futures!=null&&futures.size()>0){
for (Future<List> future:futures){
result.addAll(future.get());
}
}
executorService.shutdown();//关闭线程池
long end = System.currentTimeMillis();
System.out.println("线程查询数据用时:"+(end-start)+"ms");
return result;
}
}
19600多条数据3秒内查询完,对于之前10m查询完毕,已经提高很多的效率了
修改查询逻辑,直接在单线程中执行:
public List<List> getMaxResult(String table) {
long start = System.currentTimeMillis();//开始时间
List<List> result = new ArrayList<>();//返回结果
//查询数据库总数量
int count = sqlHadle.count(table);
int num = 8000;//一次查询多少条
//需要查询的次数
int times = count / num;
if (count % num != 0) {
times = times + 1;
}
//开始页数 连接的是orcle的数据库 封装的分页方式 我的是从1开始
int bindex = 1;
for (int i = 0; i < times; i++) {
List<List> queryResult = sqlHadle.queryData(bindex, num, table); // 修改为实际的查询方法,返回结果集List<List>
result.addAll(queryResult); // 将查询结果添加到总结果集中
bindex += num; // 更新下一次查询的开始页数
}
// 将 result 插入到相应表中,可以在此调用插入的方法,将 result 作为参数
// insertIntoTable(result);
long end = System.currentTimeMillis();
System.out.println("单线程查询数据用时:" + (end - start) + "ms");
return result;
}
public List<List> queryData(int bindex, int num, String table) {
List<List> result = new ArrayList<>(); // 存储查询结果的列表
// 构造查询语句
String sql = "SELECT * FROM " + table + " LIMIT " + bindex + ", " + num;
// 执行查询操作,并将结果存储到 result 中
// 请根据您使用的数据库和框架,使用合适的方式执行查询并得到结果
return result;
}
标签:java,int,List,查询,Callable,num,bindex,table,多线程
From: https://www.cnblogs.com/codeLearn/p/17995004