java查询数据库百万条数据,优化:多线程+数据库
java百万查询语句优化
业务需求
今天去面试时hr问了个关于大量数据查询的问题。
面试官:“我们公司是做数据分析的,每次需要从数据库中查询100万条数据进行分析,不能用分页,请问怎么优化sql或者java代码呢??”
如果用普通查询需要5分多分钟才查询完毕,所以我们用索引加多线程来实现。
那我们就开始吧!GO!!GO!!
数据库设计
编写数据库字段
然后要生成100万条数据
在数据库添加索引
索引这个方面我还是不太了解,大家懂的可以优化索引
代码实现
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(*) as sum FROM sysuser")
Integer UserSum();
/**
* 检索user表的所有记录
* @return 所有记录信息
*/
@Select("select * from sysuser LIMIT #{startLen},5000")
ArrayList<User> 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;
/**
* 用户查询多线程用户Controller
* @author 薄荷蓝柠
* @since 2023/6/6
*/
@Mapper
public interface UserMapper {
/**
* 检索user表id包含有“0”的长度
* @return 表长度
*/
@Select("SELECT count(*) as sum FROM sysuser where id like concat('%',0,'%')")
Integer UserSum();
/**
* 检索user表id包含有“0”的所有记录
* @return 所有记录信息
*/
@Select("select * from sysuser where id like concat('%',0,'%') LIMIT #{startLen},5000")
ArrayList<User> subList(@Param("startLen") int startLen);
}
修改完成后我们再测试一波–>
耗时5秒左右,可以满足业务需求
结束
目前基本的查询已经写完
看到这个文章的还可以对以下方面进行优化:
- 索引进行优化。
- 每个线程查询多少条数据最为合适??
- 如果配置有线程池可以使用:总条数/线程数==每个线程需要查询多少条数据。
- 进行代码优化,优化一些耗时的代码。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbjhbh
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13