当前位置: 首页 > 后端技术 > PHP

解决数据库N+1查询问题

时间:2023-03-29 23:41:35 PHP

需求数据表如下:departmenttable|id|name|usertable|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`');//手动将返回结果处理成需求结构。这种方法实际上有局限性。如果用户和部门不在同一台服务器上,则无法链接表。方法三: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=>部门项目]foreach($departmentsas$department){$map[$department['id']]=$department;}foreach($usersas$user){$user['department']=$map[$user['department_id']]??无效的;}这种方式对两张表没有限制,在微服务盛行的当下是一种比较好的方式。