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

Detaillierte Erklärung zur Verwendung des Linux-Befehls mpstat

1. mpstat-Befehl 1.1 Befehlsformat mpstat [ -A ] ...

...

Verwenden einer MySQL-Datenbank im Docker, um LAN-Zugriff zu erhalten

1. Holen Sie sich das MySQL-Image Docker-Pull MyS...

Der vollständige Implementierungsprozess von Sudoku mit JavaScript

Inhaltsverzeichnis Vorwort So lösen Sie Sudoku Fü...

Wird die Tabelle durch ein Update in einer MySQL-Transaktion gesperrt?

Zwei Fälle: 1. Mit Index 2. Ohne Index Voraussetz...

Lösung für die verstümmelte Anzeige von Linux SecureCRT

Sehen wir uns die Situation an, in der SecureCRT ...

Detaillierte Beschreibung der Unicode-Signatur-BOM

Unicode-Signatur-BOM – Was ist die BOM? BOM ist di...

Einfaches Beispiel für den Grenzwertparameter der MySQL-Paging

Zwei Parameter der MySQL-Paging Wählen Sie * aus ...

So aktivieren Sie das langsame Abfrageprotokoll in MySQL

1.1 Einleitung Durch Aktivieren des Slow Query Lo...

MySql-Anmeldekennwort vergessen und Lösung für vergessenes Kennwort

Methode 1: MySQL bietet einen Befehlszeilenparame...