Mysql如何解决数据库N+1查询问题
这篇文章主要介绍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查询问题”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。