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

Vue implementiert das Hinzufügen von Wasserzeichen zu hochgeladenen Bildern

In diesem Artikel wird der spezifische Implementi...

Warum ist die Bildlaufleiste auf der Webseite rechts angebracht?

Warum befinden sich die Bildlaufleisten der Brows...

Lösung zur Schnittstellenverformung beim Einstellen der Frameset-Höhe

Derzeit habe ich ein Projekt erstellt, die Schnitt...

So erben Sie die CSS-Zeilenhöhe

Wie wird die Zeilenhöhe vererbt?Schreiben Sie ein...

JS realisiert den Effekt des Bildwasserfallflusses

In diesem Artikel wird der spezifische JS-Code zu...

So installieren und speichern Sie die PostgreSQL-Datenbank in Docker

Überspringen Sie die Docker-Installationsschritte...

Mehrere Elemente in derselben Zeile unter Div in CSS rechtsbündig ausrichten

Methode 1: schweben: rechts Darüber hinaus wird d...

Die vollständige Liste der MIME-Typen

Was ist ein MIME-TYP? 1. Zunächst müssen wir vers...

Detaillierte Erklärung des Javascript Echarts Luftqualitätskarteneffekts

Wir müssen zunächst die Luftqualitätsdaten mit de...