Mysql solves the database N+1 query problem

Mysql solves the database N+1 query problem

Introduction

In orm frameworks, such as hibernate and mybatis, you can set associated objects, such as user objects associated with dept
If n users are found, then n dept queries are needed. Querying a user is a select operation, and querying the user's related
dept, is n times, so it is an n+1 problem, but it is more reasonable to call it 1+n.

mybatis configuration

UserMapper.xml

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

The data table is as follows:

department table

|id|name|

User Table

|id|name|department_id|

The requirement is to get data with the following structure:

[
  { "id":1, "name":"test", "department_id":1, "department":{ "id":1, "name":"Test Department"
    }
  }
]

Method 1: Loop query

Query user list

Circular user list to query the corresponding department information

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

This method performs 1+N queries (1 query to the list, N queries to the department), which has the lowest performance and is not advisable.

Method 2: Join Tables

Query user and department data through joined tables

Processing returned data

$users = $db->query('SELECT * FROM `user` INNER JOIN `department` ON `department`.`id` = `user`.`department_id`'); // Manual processing returns the result as required structure

This method actually has limitations. If the user and department are not on the same server, the tables cannot be joined.

Method 3: 1+1 query

This method first queries the user list once

Take out the department ID in the list to form an array

Query the department in step 2

Merge final data

The code is roughly as follows:

$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 = []; // [department ID => department item]foreach($departments as $department) {
  $map[$department['id']] = $department;
}foreach($users as $user) {
  $user['department'] = $map[$user['department_id']] ?? null;
 }

This method has no restrictions on the two tables and is a better approach given the current popularity of microservices.

You may also be interested in:
  • SQL query for users who have logged in for at least n consecutive days
  • MySQL gets the first N records of all categories
  • How to find numbers that appear more than n times in a row in mysql

<<:  How to implement property hijacking with JavaScript defineProperty

>>:  Implementation steps for building a local web server on Centos8

Recommend

Nginx anti-crawler strategy to prevent UA from crawling websites

Added anti-crawler policy file: vim /usr/www/serv...

CSS3 achieves cool sliced ​​image carousel effect

Today we will learn how to use CSS to create a co...

Pure JavaScript to implement the number guessing game

Develop a number guessing game that randomly sele...

foreman ubuntu16 quick installation

Quickstart Guide The Foreman installer is a colle...

A brief introduction to Linux environment variable files

In the Linux system, environment variables can be...

Detailed explanation of common methods of JavaScript arrays

Table of contents Common array methods pop() unsh...

Vue: Detailed explanation of memory leaks

What is a memory leak? A memory leak means that a...

Tutorial on how to install and use Ceph distributed software under Linux

Table of contents Preface 1. Basic Environment 1....

10 Tips for Mobile App User Interface Design

Tip 1: Stay focused The best mobile apps focus on...

JavaScript anti-shake and throttling detailed explanation

Table of contents Debounce Throttle Summarize Deb...

Discussion on the Issues of Image Button Submission and Form Repeated Submission

In many cases, in order to beautify the form, the ...

MySQL Series 12 Backup and Recovery

Table of contents Tutorial Series 1. Backup strat...

Using JavaScript in HTML

The <script> tag In HTML5, script has the f...