我的编程空间,编程开发者的网络收藏夹
学习永远不晚

java查询数据库百万条数据,优化之:多线程+数据库

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

java查询数据库百万条数据,优化之:多线程+数据库

java百万查询语句优化

业务需求

今天去面试时hr问了个关于大量数据查询的问题。

面试官:“我们公司是做数据分析的,每次需要从数据库中查询100万条数据进行分析,不能用分页,请问怎么优化sql或者java代码呢??”

如果用普通查询需要5分多分钟才查询完毕,所以我们用索引加多线程来实现。

那我们就开始吧!GO!!GO!!

数据库设计

编写数据库字段

然后要生成100万条数据

image-20230606110030790

在数据库添加索引

image-20230606112107605

索引这个方面我还是不太了解,大家懂的可以优化索引

代码实现

java编写

controller类编写

package com.neu.controller; import com.neu.mapper.UserMapper;import com.neu.pojo.User;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import javax.annotation.Resource;import java.util.*;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors; @Controllerpublic class ExecutorUtils {   @Resource   private UserMapper userMapper;    // 一个线程最大处理数据量   private static final int THREAD_COUNT_SIZE = 5000;   @RequestMapping("Executor")   public List executeThreadPool() {      //计算表总数      Integer integer = userMapper.UserSum();      //记录开始时间      long start = System.currentTimeMillis();      //new个和表总数一样长的ArrayList      List threadList=new ArrayList<>(integer);      // 线程数,以5000条数据为一个线程,总数据大小除以5000,再加1      int round = integer / THREAD_COUNT_SIZE + 1;      //new一个临时储存List的Map,以线程名为k,用做list排序      Map temporaryMap = new HashMap<>(round);      // 程序计数器      final CountDownLatch count = new CountDownLatch(round);      // 创建线程      ExecutorService executor = Executors.newFixedThreadPool(round);      // 分配数据      for (int i = 0; i < round; i++) {         //该线程的查询开始值         int startLen = i * THREAD_COUNT_SIZE;         int k = i + 1;         executor.execute(new Runnable() {            @Override            public void run() {               ArrayList users = userMapper.subList(startLen);               //把查出来的List放进临时Map               temporaryMap.put(k,users);               System.out.println("正在处理线程【" + k + "】的数据,数据大小为:" + users.size());               // 计数器 -1(唤醒阻塞线程)               count.countDown();            }         });      }      try {         // 阻塞线程(主线程等待所有子线程 一起执行业务)         count.await();         //结束时间         long end = System.currentTimeMillis();         System.out.println("100万数据查询耗时:" + (end - start) + "ms");         //通过循环遍历临时map,把map的值有序的放进List里         temporaryMap.keySet().forEach(k->{            threadList.addAll(temporaryMap.get(k));         });      } catch (Exception e) {         e.printStackTrace();      } finally {         //清除临时map,释放内存         temporaryMap.clear();         // 终止线程池         // 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。若已经关闭,则调用没有其他作用。         executor.shutdown();      }      //输出list的长度      System.out.println("list长度为:"+threadList.size());      return threadList;   }}

编写Mapper

package com.neu.mapper;import java.util.ArrayList;import java.util.List;import org.apache.ibatis.annotations.*;import com.neu.pojo.User;@Mapperpublic interface UserMapper {        @Select("SELECT count(*) as sum FROM sysuser")Integer UserSum();     @Select("select * from sysuser LIMIT #{startLen},5000")ArrayList subList(@Param("startLen") int startLen);}

编写完成后我们测试一波–>

测试结果20秒内,比之前快了好多

模糊查询

模糊查询呢?

咱测试一下:

修改Mapper

package com.neu.mapper;import java.util.ArrayList;import java.util.List;import org.apache.ibatis.annotations.*;import com.neu.pojo.User;@Mapperpublic interface UserMapper {         @Select("SELECT count(*) as sum FROM sysuser where id like concat('%',0,'%')")Integer UserSum();     @Select("select * from sysuser  where id like concat('%',0,'%') LIMIT #{startLen},5000")ArrayList subList(@Param("startLen") int startLen);}

修改完成后我们再测试一波–>

image-20230606110806810

耗时5秒左右,可以满足业务需求

结束

目前基本的查询已经写完

看到这个文章的还可以对以下方面进行优化:

  1. 索引进行优化。
  2. 每个线程查询多少条数据最为合适??
  3. 如果配置有线程池可以使用:总条数/线程数==每个线程需要查询多少条数据。
  4. 进行代码优化,优化一些耗时的代码。

来源地址:https://blog.csdn.net/m0_57647880/article/details/131064291

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

java查询数据库百万条数据,优化之:多线程+数据库

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java查询数据库百万条数据,优化之:多线程+数据库

java百万查询语句优化 业务需求 今天去面试时hr问了个关于大量数据查询的问题。 面试官:“我们公司是做数据分析的,每次需要从数据库中查询100万条数据进行分析,不能用分页,请问怎么优化sql或者java代码呢??” 如果用普通查询
2023-08-16

oracle百万数据查询怎么优化

使用合适的索引:在查询大量数据时,使用合适的索引可以大大提高查询性能。确保数据表上的列经常被查询的列上创建索引,以加速查询速度。使用分页查询:如果查询结果集很大,可以考虑使用分页查询,每次只查询一部分数据,而不是一次性查询全部数据。使用
oracle百万数据查询怎么优化
2024-04-09

MySQL 百万级数据分页查询优化

方法1: 直接使用数据库提供的SQL语句语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N适应场景: 适用于数据量较少的情况(元组百/千级)原因/缺点: 全表扫描,速度会很慢 且 有的数据库结果集返回不稳定(如某次
MySQL 百万级数据分页查询优化
2020-02-11

sql server 百万级数据库优化方案

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t whe
sql server 百万级数据库优化方案
2017-09-04

MySQL 百万级数据的4种查询优化方式

目录一.limit越往后越慢的原因二.百万数据模拟1、创建员工表和部门表,编写存储过程插数据2.执行存储过程三.4种查询方式1.普通limit分页2.使用索引覆盖+子查询优化3.起始位置重定义4,降级策略(百度的做法)一.limit越往后越
2022-05-28

mysql数据库表的多条件查询

mysql数据库表的多条件查询 一、select语句基本查询 SELECT 字段1,字段2....FROM 表名[WHERE 条件] [LIMIT N][ OFFSET M] select可以返回多条数据也可以返回一条数据如果要查询所有的字
2023-08-22

怎么在mysql中优化百万级数据表的查询

怎么在mysql中优化百万级数据表的查询?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1.两种查询引擎查询速度(myIsam 引擎 )InnoDB 中不保存表的
2023-06-15

MySQL数据库查询之多表查询总结

最近遇到了多表查询的需求,也称为关联查询,指两个或更多个表一起完成查询操作,下面这篇文章主要给大家介绍了关于MySQL数据库查询之多表查询的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2022-11-13

Laravel8中如何优化数据库查询

这篇文章主要介绍了Laravel8中如何优化数据库查询的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Laravel8中如何优化数据库查询文章都会有所收获,下面我们一起来看看吧。
2023-06-29

MySQL INSERT锁与数据库查询优化

INSERT锁是MySQL中的一种锁机制,在执行INSERT操作时会对表进行锁定,防止其他事务同时对同一行数据进行修改。这可以确保数据的一致性和完整性,避免数据丢失或错误。INSERT锁是一种独占锁,只有在插入操作完成后才会释放。数据库查
MySQL INSERT锁与数据库查询优化
2024-08-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录