Mysql löst das N+1-Abfrageproblem der Datenbank

Mysql löst das N+1-Abfrageproblem der Datenbank

Einführung

In Orm-Frameworks wie Hibernate und Mybatis können Sie verknüpfte Objekte festlegen, z. B. Benutzerobjekte, die mit Dept verknüpft sind.
Wenn n Benutzer gefunden werden, sind n Abteilungsabfragen erforderlich. Die Abfrage eines Benutzers ist eine Auswahloperation, und die Abfrage der zugehörigen Benutzer
Abteilung ist n-mal, also ist es ein n+1-Problem, aber es ist sinnvoller, es 1+n zu nennen.

Mybatis-Konfiguration

UserMapper.xml

<resultMap id="BaseResultMap" Typ="testmaven.entity.User">
  <id Spalte="id" jdbcType="INTEGER" Eigenschaft="id" />
  <Ergebnis Spalte="Name" jdbcType="VARCHAR" Eigenschaft="Name" />
  <Ergebnis Spalte="Alter" jdbcType="INTEGER" Eigenschaft="Alter" />
  <Ergebnisspalte="dept_id" jdbcType="INTEGER" Eigenschaft="deptId" />
  <association property="Abteilung" column="Abteilungs-ID" fetchType="eager" select="testmaven.mapper.DeptMapper.selectByPrimaryKey" ></association>
 </resultMap>

Die Datentabelle sieht wie folgt aus:

Abteilungstabelle

|ID|Name|

Benutzertabelle

|id|Name|Abteilungs-ID|

Voraussetzung ist, Daten mit folgender Struktur zu erhalten:

[
  { "id":1, "name":"test", "department_id":1, "abteilung":{ "id":1, "name":"Testabteilung"
    }
  }
]

Methode 1: Schleifenabfrage

Benutzerliste abfragen

Zirkuläre Benutzerliste zur Abfrage der entsprechenden Abteilungsinformationen

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

Diese Methode führt 1+N Abfragen aus (1 Abfrage an die Liste, N Abfragen an die Abteilung), hat die niedrigste Leistung und ist nicht ratsam.

Methode 2: Tabellen verknüpfen

Abfragen von Benutzer- und Abteilungsdaten über verknüpfte Tabellen

Verarbeitung zurückgegebener Daten

$users = $db->query('SELECT * FROM `user` INNER JOIN `department` ON `department`.`id` = `user`.`department_id`'); // Manuelle Verarbeitung gibt das Ergebnis als erforderliche Struktur zurück

Diese Methode hat tatsächlich Einschränkungen. Wenn sich Benutzer und Abteilung nicht auf demselben Server befinden, können die Tabellen nicht verknüpft werden.

Methode 3: 1+1 Abfrage

Diese Methode fragt zunächst einmal die Benutzerliste ab

Nehmen Sie die Abteilungs-ID aus der Liste heraus, um ein Array zu bilden

Abfrage der Abteilung in Schritt 2

Endgültige Daten zusammenführen

Der Code sieht ungefähr so ​​aus:

$Benutzer = $db->query('SELECT * FROM `Benutzer`');
$departmentIds = [ ]; foreach($users als $user) { wenn(!in_array($user['department_id'], $departmentIds)) {
    $departmentIds[] = $user['Abteilungs-ID'];
  }
}
$departments = $db->query('SELECT * FROM `department` WHERE id in ('.join(',',$department_id).')');
$map = []; // [Abteilungs-ID => Abteilungselement]foreach($departments as $department) {
  $map[$Abteilung['id']] = $Abteilung;
}foreach($Benutzer als $Benutzer) {
  $user['Abteilung'] = $map[$user['Abteilungs-ID']] ?? null;
 }

Bei dieser Methode gibt es keine Einschränkungen hinsichtlich der beiden Tabellen, und angesichts der aktuellen Beliebtheit von Microservices stellt sie einen besseren Ansatz dar.

Das könnte Sie auch interessieren:
  • SQL-Abfrage für Benutzer, die sich an mindestens n aufeinanderfolgenden Tagen angemeldet haben
  • MySQL ruft die ersten N Datensätze aller Kategorien ab
  • So finden Sie Zahlen, die in MySQL mehr als n-mal hintereinander vorkommen

<<:  So implementieren Sie Property Hijacking mit JavaScript defineProperty

>>:  Implementierungsschritte zum Erstellen eines lokalen Webservers auf Centos8

Artikel empfehlen

Beispielanalyse der MySQL-Indexabdeckung

Dieser Artikel beschreibt die MySQL-Indexabdeckun...

Zabbix konfiguriert DingTalks Alarmfunktion mit Bildern

Umsetzungsideen: Zunächst müssen die Alarminforma...

Detaillierte Darstellung des MySQL 5.7.33-Installationsprozesses

Inhaltsverzeichnis Download des Installationspake...

Erste Schritte Tutorial für Anfänger⑧: Einfaches Erstellen einer Artikel-Site

In meinem letzten Beitrag habe ich darüber gesproc...

So verwenden Sie den Linux-Befehl „locate“

01. Befehlsübersicht Der Befehl „locate“ ist eige...

Erstellen von responsiven E-Mails mit Vue.js und MJML

MJML ist ein modernes E-Mail-Tool, mit dem Entwic...

So rufen Sie einen HTML-Code auf mehreren HTML-Seiten gemeinsam auf

Methode 1: Skriptmethode verwenden: Erstellen Sie...

So bedienen Sie JSON-Felder in MySQL

MySQL 5.7.8 führte das JSON-Feld ein. Dieser Feld...