>일일 프로그램 >MySQL 지식 >데이터베이스 N+1 쿼리 문제 해결

데이터베이스 N+1 쿼리 문제 해결

步履不停
步履不停원래의
2019-06-19 09:40:049843검색

데이터베이스 N+1 쿼리 문제 해결

Requirements

데이터 테이블은 다음과 같습니다.

department table

|id|name|

user table

|id|name|department_id|

요구 사항은 다음 구조의 데이터를 가져오는 것입니다. :

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

방법 1 :루프 쿼리

  1. 사용자 목록 쿼리

  2. 사용자 목록을 루프하여 해당 부서 정보를 쿼리

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

이 방법의 쿼리 수는 1+N(쿼리 한 번 나열하고 부서를 N 번 쿼리), 성능이 가장 낮으므로 권장되지 않습니다.

方法二:连表

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

  2. 处理返回数据

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

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

方法三:1+1查询

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

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

  3. 查询步骤2中的部门

  4. 合并最终数据

代码大致如下:

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

该方法对两个表没有限制,在目前微服务盛行的情况下是比较好的一种做法。

更多MySQL相关技术文章,请访问MySQL教程栏目进行学习!

위 내용은 데이터베이스 N+1 쿼리 문제 해결의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.