首页 > 编程语言 >java用多线程批次查询大量数据(Callable返回数据)方式

java用多线程批次查询大量数据(Callable返回数据)方式

时间:2024-01-29 17:58:25浏览次数:30  
标签:java int List 查询 Callable num bindex table 多线程

我看到有的数据库是一万条数据和八万条数据还有十几万条,几百万的数据,然后我就想拿这些数据测试一下,发现如果用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

相关文章

  • java 两个mongo库数据迁移
    publicstaticvoidmain(String[]args){Stringcollectionname="test";//MongoDBURIStringuri="mongodb://用户名:密码@ip:端口/mydatabase?authSource=mongo";//Connecttothedatabaseusingtheprovi......
  • java反射获取类字段值以及注解描述
    publicstaticMap<String,String>getFieldNameAndDescriptionMap(Objectentity)throwsIllegalAccessException{Class<?>clazz=entity.getClass();Field[]fields=clazz.getDeclaredFields();//获取所有字段Map<String,String&g......
  • Java代码审计-FileOperations
    常见文件读写常见文件读写方式通过FileInputStream读取文件并使用FileOutputStream写入另一个文件的测试方法通过BufferedInputStream读取文件并使用BufferedOutputStream写入另一个文件的测试方法通过BufferedReader读取文件并使用BufferedWriter写入另一个文件的测试方法......
  • Java代码审计-SSRF
    SSRF漏洞SSRF(Server-SideRequestForgery:服务器端请求伪造)是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部服务器系统。支持的协议fil......
  • Java代码审计-XXE
    一、XXE漏洞简介XXE(XML外部实体注入,XMLExternalEntity),在应用程序解析XML输入时,当允许引用外部实体时,可构造恶意内容,导致读取任意文件、探测内网端口、攻击内网网站、发起DoS拒绝服务攻击、执行系统命令等。Java中的XXE支持sun.net.www.protocol里的所有协议:http,https,file,f......
  • Java代码审计-FileUpload
    Web应用通常都会包含文件上传功能,用户可以将其本地的文件上传到Web服务器上。如果服务器端没有能够正确的检测用户上传的文件类型是否合法(例如上传了jsp后缀的WebShell)就将文件写入到服务器中就可能会导致服务器被非法入侵。漏洞成因后缀名无限制//导入必要的类库package......
  • javax.annotation.Nullable找不到
    您需要包括一个存在该类的罐子。您可以在这里找到它如果使用Maven,则可以添加以下依赖项声明:<dependency><groupId>com.google.code.findbugs</groupId><artifactId>jsr305</artifactId><version>3.0.2</version></dependency>对于Gradle:dependencies......
  • Windows下安装和配置Java JDK
    1、......
  • 配置java环境(Redhat)
    安装前准备:下载java的Jdkhttps://www.oracle.com/java/technologies/downloads/   (jdk-8u202-linux-x64.tar.gz)1.查看系统是否有java环境: java-version2.如果有版本输出则需要卸载之前的jdk,找出安装的jdk: rpm-qa|grepjdk3.根据 rpm-qa|grepjdk命令列出的......
  • JVM(Java虚拟机) 整理
    JVM整体结构本文主要说的是HotSpot虚拟机,JVM全称是JavaVirtualMachine,中文译名:Java虚拟机简化一下:Java字节码文件Class文件本质上是一个以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件中,JVM根据其特定的规则解析该二进制数据,从而得到......