这篇文章主要介绍Mysql如何解决数据库N+1查询问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

简介

在orm框架中,比如hibernate和mybatis都可以设置关联对象,比如user对象关联dept
假如查询出n个user,那么需要做n次查询dept,查询user是一次select,查询user关联的
dept,是n次,所以是n+1问题,其实叫1+n更为合理一些。

mybatis配置

UserMapper.xml

<resultMapid="BaseResultMap"type="testmaven.entity.User"><idcolumn="id"jdbcType="INTEGER"property="id"/><resultcolumn="name"jdbcType="VARCHAR"property="name"/><resultcolumn="age"jdbcType="INTEGER"property="age"/><resultcolumn="dept_id"jdbcType="INTEGER"property="deptId"/><associationproperty="dept"column="dept_id"fetchType="eager"select="testmaven.mapper.DeptMapper.selectByPrimaryKey"></association></resultMap>

数据表如下:

department表

|id|name|

user表

|id|name|department_id|

需求是得到以下结构的数据:

[{"id":1,"name":"test","department_id":1,"department":{"id":1,"name":"测试部门"}}]

方法一:循环查询

查询用户列表

循环用户列表查询对应的部门信息

$users=$db->query('SELECT*FROM`user`');foreach($usersas&$user){$users['department']=$db->query('SELECT*FROM`department`WHERE`id`='.$user['department_id']);}

该方法查询次数为:1+N(1次查询列表,N次查询部门),性能最低,不可取。

方法二:连表

通过连表查询用户和部门数据

处理返回数据

$users=$db->query('SELECT*FROM`user`INNERJOIN`department`ON`department`.`id`=`user`.`department_id`');//手动处理返回结果为需求结构

该方法其实也有局限性,如果 user 和 department 不在同一个服务器是不可以连表的。

方法三:1+1查询

该方法先查询1次用户列表

取出列表中的部门ID组成数组

查询步骤2中的部门

合并最终数据

代码大致如下:

$users=$db->query('SELECT*FROM`user`');$departmentIds=[];foreach($usersas$user){if(!in_array($user['department_id'],$departmentIds)){$departmentIds[]=$user['department_id'];}}$departments=$db->query('SELECT*FROM`department`WHEREidin('.join(',',$department_id).')');$map=[];//[部门ID=>部门item]foreach($departmentsas$department){$map[$department['id']]=$department;}foreach($usersas$user){$user['department']=$map[$user['department_id']]??null;}

以上是“Mysql如何解决数据库N+1查询问题”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!