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

这篇具有很好参考价值的文章主要介绍了java查询数据库百万条数据,优化之:多线程+数据库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

java百万查询语句优化

业务需求

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

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

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

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

数据库设计

编写数据库字段

然后要生成100万条数据

多线程查询数据库,maven,spring boot,java,数据库,servlet

在数据库添加索引

多线程查询数据库,maven,spring boot,java,数据库,servlet

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

代码实现

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;
 
/**
 * 用户查询多线程用户Controller
 * @author 薄荷蓝柠
 * @since 2023/6/6
 */
@Controller
public class ExecutorUtils {

   @Resource
   private UserMapper userMapper;

 
   // 一个线程最大处理数据量
   private static final int THREAD_COUNT_SIZE = 5000;



   @RequestMapping("Executor")
   public List<User> executeThreadPool() {

      //计算表总数
      Integer integer = userMapper.UserSum();

      //记录开始时间
      long start = System.currentTimeMillis();


      //new个和表总数一样长的ArrayList
      List<User> threadList=new ArrayList<>(integer);

      // 线程数,以5000条数据为一个线程,总数据大小除以5000,再加1
      int round = integer / THREAD_COUNT_SIZE + 1;

      //new一个临时储存List的Map,以线程名为k,用做list排序
      Map<Integer,ArrayList> 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<User> 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;

/**
 * 用户查询多线程用户Controller
 * @author 薄荷蓝柠
 * @since 2023/6/6
 */
@Mapper
public interface UserMapper {
    
    /**
	 * 检索user表的长度
	 * @return 表长度
	 */
	@Select("SELECT count(id) as sum FROM sysuser")
	Integer UserSum();

     /**
	 * 检索user表的所有记录,
	 * SELECT * 无法使用 MySQL 优化器覆盖索引的优化(基于 MySQL 优化器的“覆盖索引”策略又是速度极快,效率极高,业界极为推荐的查询优化方式)
	 * @return 所有记录信息
	 */
	@Select("select id,account,password,name,job,rights,roleId,createUserId,createTime,updateUserId,updateTime,del,enable from sysuser LIMIT #{startLen},5000")
	ArrayList<User> subList(@Param("startLen") int startLen);
}

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

多线程查询数据库,maven,spring boot,java,数据库,servlet

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

模糊查询

模糊查询呢?

咱测试一下:

修改Mapper
package com.neu.mapper;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.annotations.*;

import com.neu.pojo.User;

/**
 * 用户查询多线程用户Controller
 * @author 薄荷蓝柠
 * @since 2023/6/6
 */
@Mapper
public interface UserMapper {
	
    
     /**
	 * 检索user表id包含有“0”的长度
	 * @return 表长度
	 */
	@Select("SELECT count(id) as sum FROM sysuser where id like concat('%',0,'%')")
	Integer UserSum();

     /**
	 * 检索user表id包含有“0”的所有记录
	 * SELECT * 无法使用 MySQL 优化器覆盖索引的优化(基于 MySQL 优化器的“覆盖索引”策略又是速度极快,效率极高,业界极为推荐的查询优化方式)
	 * @return 所有记录信息
	 */
	@Select("select id,account,password,name,job,rights,roleId,createUserId,createTime,updateUserId,updateTime,del,enable from sysuser  where id like concat('%',0,'%') LIMIT #{startLen},5000")
	ArrayList<User> subList(@Param("startLen") int startLen);
}

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

多线程查询数据库,maven,spring boot,java,数据库,servlet

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

结束

目前基本的查询已经写完

看到这个文章的还可以对以下方面进行优化:文章来源地址https://www.toymoban.com/news/detail-615072.html

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

到了这里,关于java查询数据库百万条数据,优化之:多线程+数据库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MYSQL中1000万条数据你是怎么查询的,查询非常慢怎么优化

     数据量越大,花费时间越长   偏移量越大,花费时间越长(浅层分页到深层分页) SQL优化: 1.MySQL自身 2.网络IO 3.SQL自身 --原SQL --避免使用select *  全表扫描,查询效率慢 --按需查找字段    使用索引扫描,主键索引,进行提升 --覆盖索引 查询字段索引覆盖,通过辅助索引提

    2024年02月06日
    浏览(31)
  • for循环查询数据库优化(挺好用的)

    前段时间在完成一个列表功能的时候发现我for循环里嵌套了2个查询语句,然后就感觉太影响性能了,而且也体现一个人的水平, 这里我举下例子(方便回忆)。 如果性能还是没有得到解决的话,建议结合定时器以及检查sql是否失效,或者走索引。 1.sql优化 sql优化 2.数据库做

    2023年04月08日
    浏览(25)
  • 近8万条中国历史野史秘闻ACCESS数据库

    有很多朋友对中国文化历史相关的数据感兴趣,现有的中华上下五千年、世界五千年这类的数据记录数还太少太少,于是今天就采集了一个中华历史网站,共有效采集到近8万条记录。 分类汇总情况:野史秘闻(12273)、历史人物(8840)、历史杂谈(7928)、文史百科(5635)、

    2024年02月07日
    浏览(31)
  • MySQL数据库索引优化指南:提升查询效率的利器

    本文将详细探讨MySQL数据库索引的概念、作用以及不同类型的索引,包括主键索引、唯一索引和普通索引。通过实际案例分析,我们将深入理解索引的工作原理,并提供实用的优化建议,帮助读者提升数据库性能。

    2024年02月09日
    浏览(62)
  • 上万条全球各国纸币大全含图ACCESS数据库

    《上万条全球各国纸币大全含图ACCESS数据库》是今天采集自钱币大全网站的纸币资料,大类包含:中国大陆、中国台湾、中国香港、中国澳门、亚洲纸钞、欧洲纸钞、美洲纸钞、非洲纸钞 、大洋洲、其他纸钞等,而且纸币信息包含:国家名称、英文名称、目录编号、纸钞面额

    2024年02月06日
    浏览(34)
  • 玩转MySQL数据库之SQL优化之慢查询

    本系列为:MySQL数据库详解,为千锋资深教学老师独家创作,致力于为大家讲解清晰MySQL数据库相关知识点,含有丰富的代码案例及讲解。如果感觉对大家有帮助的话,可以【关注】持续追更~ 文末有本文重点总结,技术类问题,也欢迎大家和我们沟通交流! 从今天开始本系列

    2024年02月06日
    浏览(69)
  • Django笔记二十八之数据库查询优化汇总

    本文首发于公众号:Hunter后端 原文链接:Django笔记二十八之数据库查询优化汇总 这一篇笔记将从以下几个方面来介绍 Django 在查询过程中的一些优化操作,有一些是介绍如何获取 Django 查询转化的 sql 语句,有一些是理解 QuerySet 是如何获取数据的。 以下是本篇笔记目录: 性

    2023年04月22日
    浏览(59)
  • 2万条中华灯谜精选ACCESS\EXCEL数据库

    灯谜,即写在彩灯上面的谜语,又叫“灯虎”。猜灯谜又叫“射灯虎”。谜语来源于民间口谜,后经文人加工成为谜,它在中国源远流长。春秋战国时期,出现了“隐语”或“庾辞”。秦汉时则成为一种书面创作。三国时代,猜谜盛行。在宋代出现了灯谜。人们将谜条系于五

    2024年02月07日
    浏览(30)
  • 近8万条谜语灯谜大全ACCESS\EXCEL数据库

    其实互联网上关于谜语和灯谜的资料仍然是挺多的,但是要想数据量以万来计算并且是接近10万的量来看的话,就只能是《近8万条谜语灯谜大全ACCESS数据库》了。而且《近8万条谜语灯谜大全ACCESS数据库》的数据表字段中也包含分类字段,可以根据分类字段有针对性的给出谜语

    2024年02月06日
    浏览(35)
  • 近万条英文智力问答题库ACCESS\EXCEL数据库

    今天弄到了一份很不错的英文版智力问答题库,属于那种我很满意的数据库,原因有:1.记录数将近1万条达到库的基础;2.分类表信息包含大小分类非常详细;3.题目内容包含六七百条含有图片的题;4.题库除了选择题外还包含判断题,具体看以下截图: 题止表中的QUIZ_PK_ID字

    2024年02月07日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包