for循环查询数据库优化(挺好用的)

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

前段时间在完成一个列表功能的时候发现我for循环里嵌套了2个查询语句,然后就感觉太影响性能了,而且也体现一个人的水平, 这里我举下例子(方便回忆)。

实体

//项目用户实体首先这是和用户实体一对多的关系,既一个项目下有多个用户这样我们查询这个数据库时候就会出现list列表传个projectId进来
public class ProjectUser {

    private  String userId;

    private String projectId;
}
//用户实体
public class User {

    private  String id;

    private String imageId;

	private String userName;

}
//头像实体类
public class Image {

    private  String id;

    private String imageUrl;
}
//出参
public class UserInfoVO{

	private String projectId;
	//这里返回给前端一个列表数组
	private List<UserInfo> userInfoList;

}
public class UserInfo{
	private Sring userName;
	
	private Sring userId;
	
	private Sring imageUrl
}
    

实际碰到的问题(优化前)

//需求:我们需要返回一个列表给前端,这个列表包含的数据有用户id,用户头像,用户姓名,前端传个项目id进来
//菜鸟的我是这样写的
//1.我们需要通过项目id去获取这个项目下有多少个用户
//2.然后循环这个列表,获取这个集合下的userId
//3.拿到userId需要去查user表拿到用户名,还有imageid
//4.这时再拿imageId去查image表拿imageUrl获取头像
UserInfoVO userInfoVO=new UserInfoVO();
List<UserInfo> userInfoList=new ArraryList<>();
List<ProjectUser > projectList=projectUserDao.selectByProjectId(projectId);
//这里列表可能为空的如果一些坑的项目没有会报错所以可以做非空判断
if(CollectionUtils.isNotEmpty(projectList)){
for(ProjectUser projectuser:projectList){
	UserInfo userinfo =new UserInfo();
	User user=userDao.selectByUserId(projectuser.getUserId());
	Image image=imageDao.selectByImageId(user.getImageId());
	userinfo.setUserName(user.getUserName());
	userinfo.setUserId(user.getId());
	userinfo.setImageUrl(image.getImageUrl());
	userInfoList.add(userinfo);
}
userInfoVO.setProjectId(projectId);
userInfoVO.setUserInfoList(userInfoList);
//从这里可以看出我这个for循环里嵌套了查询语句而且还是两条,这样如果数据量过大的话,每次循环都会去连接数据库,这样是容易影响性能和导致数据库崩溃的。
}

实际碰到的问题(优化后)

//这里我的优化思路是利用stream流结合sql语句进行优化
//1.首先还是查询出list集合
List<ProjectUser > projectList=projectUserDao.selectByProjectId(projectId);
//2.然后用stream流对这个集合的关键字段进行转换筛选处理,这里收集所有的userId,待会让sqlfor循环。
List<String> userIdList=projectList.stream().map(ProjectUser::getUserId).collect(Collectors.toList());
//3.写一条sql语句让sql做循环(效果比你for循环里查询数据库好)
List<UserInfoDTO> userInfoDTOList=projectUserDao.selectByUserIds(userIdList);
//4.拿到list集合利用stream流把他转换成map类型
Map<String,UserInfoDTO> userInfoMap=userInfoDTOList.stream().collect(Collectors.toMap(UserInfoDTO::getUserId,Function.identity()))
//5.接下来就是填充数据了,
for(String userId:userIdList){
	UserInfo userinfo =new UserInfo();
	UserInfoDTO userInfoDTO=userInfoMap.get(userId);
	userinfo.setUserName(userInfoDTO.getUserName());
	userinfo.setUserId(userInfoDTO.getId());
	userinfo.setImageUrl(userInfoDTO.getImageUrl());
	userInfoList.add(userinfo);
}
userInfoVO.setProjectId(projectId);
userInfoVO.setUserInfoList(userInfoList);
//从这里可以看出我优化成功,for循环里没有查询sql,所以stream流结合sql语句YYDS,只能说stream流真的太强了。
}

SQL语句

//这个类可以用来接受我们需要接受的数据
public class UserInfoDTO{
	private Sring userName;
	
	private Sring userId;
	
	private Sring imageUrl

}

	//这里是dao层
	List<UserInfoDTO> selectByUserIds(@Param("userIdList")List<String> userIdList);

//sql
	<select id="selectByUserIds" resultType="com.chenguangzhao.entities.UserInfoDTO" parameterType="java.util.List">
		select
		a.id AS userId,
		a.user_name AS userName,
		b.image_url AS imageUrl
		from t_user a
		LEFT JOIN t_image b on a.image_id=b.id
		<where>
			<if test="userIdList.size()>0">
			//这里需要标明那个表的id不然会分不清楚
				a.id in
				<foreach collection="userIdList" item="id" index="index" open="(" close=")" separator=",">
					#{id}
				</foreach>
			</if>
		</where>
	</select>

性能提高总结

如果性能还是没有得到解决的话,建议结合定时器以及检查sql是否失效,或者走索引。
1.sql优化
sql优化
2.数据库做主从复制,主库写数据,从库读数据(这一步我感觉大部分项目都是做了的)

3.定时器+reids(当然要实时查询的话还是得websocket(实时传输数据给前端)结合消息队列(观察者模式、redis发布订阅模式都可以替代消息队列)
大数据下,如果数据量比较大的话,可以尝试结合redis缓存和定时器来进行提高性能
定时器加redis优化

4.如果业务比较多的话,需要查很多表的话,建议一次性把所有的数据查出来,然后对数组进行处理以及组装过滤等操作(可以采用stream流,这个很好用这样可以减少很多for循环)

5.如果性能还得不到提高建议结合多线程对数据进行处理(能尽量用sql把所有数据查出来就查出来)
多线程提高性能

6.上面的几种情况下还不能解决问题的话考虑使用设计模式比如单例模式,享元模式(目前我也没学),策略模式+工厂模式
设计模式优化

7.通过消息队列提前把数据推到队列中,然后消费者消费队列中的数据

8.关于LEFT JOIN 语句的优化,当你数据量比较大的时候关联表比较多可能会影响到性能
LEFT JOIN 优化

9.mysql联合查询

联合查询-减少查询文章来源地址https://www.toymoban.com/news/detail-405164.html

到了这里,关于for循环查询数据库优化(挺好用的)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

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

    今天去面试时hr问了个关于大量数据查询的问题。 面试官:“我们公司是做数据分析的,每次需要从数据库中查询100万条数据进行分析,该接口不能用分页(不限制具体怎么实现),请问怎么优化sql或者java代码呢??” 如果用普通查询需要5分多分钟才查询完毕,所以我们用

    2024年02月15日
    浏览(51)
  • java八股文面试[数据库]——慢查询优化

    分析慢查询日志 直接分析慢查询日志, mysql使用 explain + sql语句进行模拟优化器来执行分析。 oracle使用explain plan for + sql语句进行模拟优化器来执行分析。 table | type | possible_keys | key |key_len | ref | rows | Extra EXPLAIN列的解释: table 显示这一行的数据是关于哪张表的 type 这是重要的

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

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

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

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

    2023年04月22日
    浏览(80)
  • 玩转MySQL数据库之SQL优化之慢查询

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

    2024年02月06日
    浏览(88)
  • 安卓查看本地sqlite数据库的好用工具

    安卓日常开发过程中可能经常会涉及到本地sqlite数据库,对本地sqlite数据库的可视化操作可清晰的看到数据库中的数据,方便我们测试和发现问题。这里推荐两种好用的安卓开发sqlite数据库本地可视化工具,以供参考。 一、使用Android studio自带的插件,比如Database Navigator,可

    2024年02月13日
    浏览(44)
  • 数据库(mysql语句)循环语句

    例题1: 20到50之间能被5除余1的所有自然数的和   例题2: 实现如下图 代码  例题3: 代码:power表示power(i,j)-----i的j次方 例题4:  实现 代码:  注:substring是从1开始,第一个参数表示要截取的字符串,第二个i和第三个j表示从第i个开始截,截取j个,如:str=HELLO, subs

    2024年02月05日
    浏览(41)
  • 数据库优化(数据库自身的优化,数据库表优化,程序操作优化)

    1. 增加次数据文件 从SQL SERVER 2005开始,数据库不默认生成NDF数据文件,一般情况下有一个主数据文件(MDF)就够了,但是有些大型的数据库,由于信息很多,而且查询频繁,所以为了提高查询速度,可以把一些表或者一些表中的部分记录分开存储在不同的数据文件里 由于C

    2024年02月14日
    浏览(47)
  • smartsofthelp 5.0 最专业的数据库优化工具,数据库配置优化,数据库高并发优化,SQL 语句优化...

      下载地址:百度网盘 请输入提取码 SQL操作返回历史记录: 2023-08-21 20:42:08:220  输入:select @@version as 版本号 2023-08-21 20:42:08:223  输出:当前数据库实例版本号:Microsoft SQL Server 2012 - 11.0.2100.60 (X64)      Feb 10 2012 19:39:15      Copyright (c) Microsoft Corporation     Developer Edition (

    2024年02月12日
    浏览(56)
  • 数据库原理-数据查询 单表查询【二】

    聚集函数: 统计元组个数 COUNT(*) 统计一列中值的个数 COUNT([DISTINCT|ALL]列名) 计算一列值的总和(此列必须为数值型) SUM([DISTINCT|[ALL]列名) 计算一列值的平均值(此列必须为数值型) AVG([DISTINCT|ALL]列名) 求一列中的最大值和最小值 MAX([DISTINCT|ALL]列名) MIN([DISTINCT|ALL]列名) 查询学

    2024年02月03日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包