Eine Verallgemeinerung von N+1
Das N+1-Problem ist ein ORM-spezifischer Name für ein Problem, bei dem man Schleifen, die sinnvollerweise auf einem Server ausgeführt werden könnten, auf den Client verschiebt. Das generische Problem ist nicht spezifisch für ORMs, es kann bei jeder Remote-API auftreten. In diesem Artikel habe ich gezeigt, dass JDBC-Roundtrips sehr kostspielig sind wenn Sie eine API N-mal statt nur 1-mal aufrufen. Der Unterschied in diesem Beispiel besteht darin, ob Sie die Oracle PL/SQL-Prozedur aufrufen:
dbms_output.get_lines
(einmaliger Aufruf, Erhalt von N Elementen)
dbms_output.get_line
(N-mal aufrufen, jedes Mal 1 Element erhalten)
Sie sind logisch äquivalent, aber aufgrund der Latenzzeit zwischen Server und Client fügen Sie N Latenz-Wartezeiten zu Ihrer Schleife hinzu, anstatt nur einmal zu warten.
Der ORM-Fall
Tatsächlich ist das ORM-y N+1-Problem nicht einmal ORM-spezifisch, Sie können es auch erreichen, indem Sie Ihre eigenen Abfragen manuell ausführen, z. B. wenn Sie so etwas in PL/SQL tun:
-- This loop is executed once
for parent in (select * from parent) loop
-- This loop is executed N times
for child in (select * from child where parent_id = parent.id) loop
...
end loop;
end loop;
Es wäre viel besser, dies über eine Verknüpfung (in diesem Fall) zu realisieren:
for rec in (
select *
from parent p
join child c on c.parent_id = p.id
)
loop
...
end loop;
Jetzt wird die Schleife nur noch einmal ausgeführt, und die Logik der Schleife wurde vom Client (PL/SQL) auf den Server (SQL) verlagert, der sie sogar noch anders optimieren kann, z. B. durch einen Hash Join ( O(N)
) als eine verschachtelte Schleifenverbindung ( O(N log N)
mit Index)
Automatische Erkennung von N+1-Problemen
Wenn Sie JDBC verwenden, Sie könnten jOOQ als JDBC-Proxy hinter den Kulissen verwenden, um Ihre N+1-Probleme automatisch zu erkennen. Der jOOQ-Parser normalisiert Ihre SQL-Abfragen und speichert Daten über aufeinanderfolgende Ausführungen von Eltern- und Kind-Abfragen. Dies funktioniert sogar, wenn Ihre Abfragen nicht genau gleich, aber semantisch äquivalent sind.
2 Stimmen
Es gibt einige hilfreiche Beiträge, die sich mit diesem Problem und der möglichen Lösung befassen. Häufige Anwendungsprobleme und deren Behebung: Das Select N + 1 Problem , Die (silberne) Kugel für das N+1 Problem , Langsames Laden - eifriges Laden
0 Stimmen
Für alle, die nach einer Lösung für dieses Problem suchen, habe ich einen Beitrag gefunden, der es beschreibt. stackoverflow.com/questions/32453989/
54 Stimmen
Wenn man die Antworten bedenkt, sollte man dies nicht als 1+N Problem bezeichnen? Da es sich um eine Terminologie zu handeln scheint, frage ich nicht speziell OP.