Laravel Eloquent vs Query Builder - Warum eloquent verwenden, um die Leistung zu verringern [geschlossen]

75

Ich habe einen Leistungstest zwischen Laravel Query Builder und Beredsamkeit durchgeführt. Der Abfrage-Generator war mit verschiedenen SQL-Anweisungen (Select-Update-Delete-Insert) viel schneller.

Meine Frage lautet also: Warum verwendet jemand Laravel Eloquent gegen den einfachen Abfrage-Builder?

Panagiotis Koursaris
quelle
22
Vergleichen Sie keine Äpfel und Orangen. Eloquent ist ein ORM, dh Sie können die Beziehungen Ihrer Modelle automatisch für Sie verwalten. Sie können verwandte Modelle abrufen, ohne komplexe Abfragen zu schreiben. Sie können sogar Datenbankinformationen ohne jegliche Datenbankkenntnisse abrufen. Auch Eloquent hat Tonne zusätzliche Funktionen die die Query Builder fehlt, wie Lesbarkeit, Accessoren, Mutatoren, JSON / Array - Konvertierung, versteckt sensible Attribute, automatische timestams, automatisches Attribut Guss, sofdeletes, etc ...
Javi Stolz
78
Äpfel produzieren Apfelsaft, Orangen produzieren Orangensaft. Aber leider Eloquentund Query Builderbeide produzieren das gleiche, dataaus database. Vielleicht vergleicht er deshalb diese beiden.
Imran
4
@JaviStolz Wenn Sie gesagt hätten, ohne SQL zu kennen, hätten Sie Recht. "Sie können sogar Datenbankinformationen ohne jegliche Datenbankkenntnisse abrufen" ist jedoch nicht möglich. Für Eloquent müssen Sie die Struktur Ihrer Datenbank kennen, wissen, was Fremdschlüssel sind und wie sie funktionieren und wie Sie in der Struktur navigieren. Nur für die einfachsten Abfragen sind keine Datenbankkenntnisse erforderlich, und für die meisten Anwendungen sind hochkomplexe Abfragen erforderlich.
Michiel van der Blonk
Obwohl Äpfel Apfelsaft und Orangen Orangensaft machen, sind beide Saft. Eloquent gibt Sammlungen zurück, bei denen es sich um in Helfer verpackte Daten handelt, die die Geschäftslogik besser lesbar machen. Query Builder ist ein Teil, das von Eloquent verwendet wird. Eloquent ist eine Komponente in einem Geschäftslogik-Paradigma, mit dem Sie mithilfe von Closure Anpassungen vornehmen und die Daten in jedem Teil des Flusses filtern können, sodass Ihre Daten $object->filter($something_we_just_calculated)während der Bearbeitung eines Entscheidungsbaums gelesen werden . Sie können an Eloquent wie JQuery
Nathaniel Waddell

Antworten:

135

Eloquent ist Laravels Implementierung des Active Record-Musters und weist alle seine Stärken und Schwächen auf.

Active Record ist eine gute Lösung für die Verarbeitung einer einzelnen Entität auf CRUD-Weise. Erstellen Sie also eine neue Entität mit gefüllten Eigenschaften und speichern Sie sie in einer Datenbank, laden Sie einen Datensatz aus einer Datenbank oder löschen Sie sie.

Sie profitieren stark von Eloquents Funktionen wie Dirty Checking (um SQL UPDATE nur für die geänderten Felder zu senden), Modellereignissen (z. B. um administrative Warnungen zu senden oder Statistikzähler zu aktualisieren, wenn jemand ein neues Konto erstellt hat), Eigenschaften ( Zeitstempel, weiche Löschvorgänge, Ihre benutzerdefinierten Merkmale) eifriges / verzögertes Laden usw. Sie können auch domänengesteuerte Muster anwenden und einige Teile der Geschäftslogik in Ihre Active Record-Entitäten implementieren, z. B. Validierung, Verwaltung von Beziehungen, Berechnungen usw.

Wie Sie bereits wissen, ist Active Record mit einem gewissen Leistungspreis verbunden.

Wenn Sie einen einzelnen Datensatz oder einige Datensätze verarbeiten, müssen Sie sich keine Sorgen machen. In Fällen, in denen Sie viele Datensätze lesen (z. B. für Datagrids, Berichte, Stapelverarbeitung usw.), sind die einfachen Laravel- DBMethoden ein besserer Ansatz.

Für unsere Laravel-basierten Anwendungen verwenden wir beide Ansätze, wie wir es für angemessen halten. Wir verwenden Laravels Eloquent for UI-Formulare, um einen einzelnen Datensatz zu verarbeiten, und verwenden DBMethoden (unterstützt durch SQL-Ansichten mit zusätzlichen datenbankmodulspezifischen Leistungsverbesserungen), um Daten für UI-Tabellen abzurufen, Aufgaben zu exportieren usw. Es funktioniert auch gut mit RESTful-APIs - Eloquent for GET , PUT, POST, DELETE mit einem Schlüssel und DBfür GET ohne Schlüssel, aber mit Filtern und Sortieren und Paging.

JustAMartin
quelle
1
Behebt Eager Loading das Leistungsproblem nicht?
Christophvh
5
@Christophvh Manchmal kann eifriges Laden ein bisschen helfen, aber es bleibt immer noch das gleiche eloquente (Active Record) Objekt mit all seinen "schweren Sachen". Laravel bietet einige praktische Methoden für Eloquent-Modelle, um SQL-Abfragen und abgerufene Objekte noch einfacher zu machen. Dies ist jedoch kein reines Eloquent mehr, sondern eine Art Eloquent / QueryBuilder-Hybrid.
JustAMartin
Eloquent eignet sich perfekt für die üblichen CRUD-Operationen an einem einzelnen Modell oder für einfache JOINs, wenn Sie mit wenigen Datensätzen arbeiten. Sobald Sie jedoch mit komplexen Verknüpfungen beginnen und mit Hunderten oder Tausenden von Datensätzen in einer Transaktion arbeiten, sind Abfrageerstellungsmethoden leistungsfähiger. Wenn überhaupt, ist Raw SQL die leistungsstärkste Option, da es sich um eine direkte Abfrage handelt.
OzzyTheGiant
Ich stimme der Antwort immer noch zu, da ich jetzt der gleichen Art und Weise gegenüberstehe, dass das Laden (SELECT) mit anderen Prüfungen / Regeln von eloquent ein Schmerz ist, aber all diese zu einem Abfrage-Generator zu verschieben, ist auch eine große Herausforderung, wenn wir nicht von Anfang an planen Was wir brauchen, um die DB-Abfrage zu verwenden, was wir mit Beredsamkeit tun sollen, hoffe, dass andere sich dessen bewusst sind
Osify
Nur zur Klarstellung: Das Problem, das Laravel mit Beredsamkeit hat, ist die Instanziierung der Modelle. ZB Laravel new User()für jede zurückgegebene Benutzerzeile. Dies dauert vielleicht nur 1 ms, aber wenn Sie 10'000 Datensätze haben? Dies ist oft nicht einmal notwendig, da Sie manchmal nur den Benutzernamen zurückgeben möchten. In diesem Fall DB::selectwäre schneller. Beachten Sie auch: Beredsam ist nicht Laravels Implementierung afaik. Es ist die Implementierung von Symphony, die von Laravel angepasst wurde oder irgendwann war, wenn ich mich richtig erinnere.
Toskan
49

Ja, in einigen Fällen haben Sie recht. Wenn wir mehr Daten haben und fast auf jeder Site, sind die Daten nicht wirklich klein. Dann ist es besser, DB Query als Eloquent Query zu verwenden .

In einem Leistungsproblem von Eloquent VS DB habe ich das gehört,

Das Einfügen von 1000 Zeilen für eine einfache Tabelle Eloquent dauert 1,2 Sekunden, und in diesem Fall benötigen DB-Fassaden nur 800 Millisekunden (ms).

Warum dann Eloquent? Ist das nicht nötig?

Antwort ist - Beredsam ist auch notwendig. Ursache-

Um eine bessere Beziehung zu erstellen und die Ergebnisse mit so viel einfacher Syntax anzuzeigen, wenn eine Verbindung erforderlich ist.

Eloquent ist auch für diejenigen gedacht , die nicht viel über SQL-Abfragen wissen .

Ein MVC-Framework folgt den Regeln für Code-Lesbarkeit, Code-Wartbarkeit und was Eloquent ist, das wissen Sie. Ein Codevergleich unten. Offensichtlich ist Eloquent besser zu lesen.

// In Eloquent
$student = App\Student::find($id);

// In DB facade
$student = DB::table('student')->where('id', $id)->first();

Der wichtigste Teil ist, wenn wir eine andere Datenbank ändern möchten, wird uns die rohe Abfrage viel Kopfzerbrechen bereiten, und in diesem Fall wird Laravel Eloquent alle Probleme mit einer Hand lösen. Es kann verschiedene Arten von Datenbanken verarbeiten.

Wenn wir also Eloquent- und When DB-Fassaden verwenden:

  1. Wenn wir an einer einfachen und kleinen Datensatz-Site mit einfachem CRUD arbeiten und dort keine Fakten vorliegen, verwenden Sie dort Eloquent.
  2. Wenn wir an vielen Datensätzen arbeiten, ist es besser, DB Query als Eloquent zu verwenden.

Schließlich ist klar, dass - wann wir die Datenbankabfrage verwenden und wann wir die eloquente Abfrage verwenden.

Bearbeiten - Beispiel aus dem wirklichen Leben

  1. Ich mache eine Universitätswebsite . Welches kann maximal enthalten 5,000 teachers and 10,000 students and some notices and files. Dann ist es besser, dies mit einfachem Laravel Eloquent zu tun, das sehr normal und lesbar ist.
  2. Jetzt mache ich eine Seite wie Stackoverflow . Welches kann mehr als enthalten 1,000,0000 (1 crore) posts and many more things. Ich muss dort die konventionellen DB-Fassaden wählen. Es ist schneller, die Beiträge aus so vielen Datensätzen zu durchsuchen.

Sie können Ihre Abfrageleistung mithilfe der Laravel-Debugbar überprüfen (ein beliebtes Paket zum Überprüfen der Leistung / Ausführungszeiten von Eloquent- / Datenbankabfragen).

Jetzt haben Sie die Wahl. Was du machen willst ...

Sie können hier einen vollständigen Code durch Codevergleich mit Leistung, Speicherverbrauch und Codequalität überprüfen - https://devsenv.com/tutorials/laravel-eloquent-vs-db-query-builder-performance-and-other-statistics

Maniruzzaman Akash
quelle
4
"Wenn wir an vielen Datensätzen arbeiten" sollte "wenn wir viele Verknüpfungen und Funktionen verwenden, die von Eloquent nicht unterstützt werden" lauten. Wenn Eloquent nicht eifrig lädt, führt dies zu einem massiven Leistungseinbruch. Komplexe Aggregate und Verknüpfungen durch mehrere Spalten sind mit Eloquent derzeit schwierig. Wenn Sie über eine Million Datensätze verfügen und nur einige Datensätze aus einer Tabelle auswählen, führt Eloquent zu derselben SQL und Leistung wie DBQuery oder sogar direktes PDO.
Michiel van der Blonk
Einfache und perfekte Antwort
Juned Ansari
31

Warum Laravel Eloquent:

  1. Abfrage auf eine OOPArt und Weise ausführen .
  2. Einfach zu bedienen als Rohabfrage oder query builder.
  3. Keine Bindung mit table schema. Das heißt, selbst wenn Sie Ihren Tabellennamen ändern, müssen Sie keinen einzigen berühren query(möglicherweise 1000 query), damit er funktioniert. Ändern Sie einfach den Tabellennamen in eloquent model.
  4. Die Beziehung zwischen Tabellen kann auf elegante Weise aufrechterhalten werden. Erwähnen Sie einfach die Art der Beziehung, nichts anderes ( JOIN, LEFT JOIN, RIGHT JOINusw.), das in der Abfrage mehr benötigt wird, um Daten verwandter Tabellen zu erhalten.
  5. Abfragen sind beim Schreiben mit Eloquent im Vergleich zu Query Builder gut lesbar.
Imran
quelle
19

Wenn es um Leistung geht und die Anwendung wächst, sollten Sie zu Vergleichszwecken die folgenden Tabellen verwenden:

Vergleich der durchschnittlichen Antwortzeit für ausgewählte Operationen zwischen Eloquent ORM und Raw SQL

Eloquente ORM durchschnittliche Antwortzeit

Joins | Average (ms) 
------+-------------
1     | 162,2 
3     | 1002,7 
4     | 1540,0 

Result of select operation average response time for Eloquent ORM 

Durchschnittliche Antwortzeit für Raw SQL

Joins | Average (ms) 
------+-------------
1     | 116,4 
3     | 130,6 
4     | 155,2 

Result of select operation average response time for Raw SQL 

Artikelreferenz

Mohammad Naji
quelle
5

Es ist nur meine Meinung, keine umfassende Antwort. Ich benutze alles, was in einer bestimmten Situation bequemer ist.

Wenn ich auf ein Paket oder einen Code stoße, der entweder in eloquent oder im Abfrage-Generator geschrieben ist, verwende ich alles, was verwendet wird.

Ich fand den Abfrage-Generator intuitiver, wenn ich etwas von Grund auf neu erstelle, damit ich es häufiger verwende.

Wenn es um Laravel geht, ist die Leichtigkeit und Geschwindigkeit der Entwicklung einer App anscheinend wichtiger als die Leistung. Ich mag es wirklich, dass sie alles sehr einfach machen, selbst für jemanden mit geringen Vorkenntnissen in PHP / MySQL. In einigen Fällen ist eloquent einfacher als der Abfrage-Generator. In anderen umgekehrt. Ich denke, viele Möglichkeiten zu haben, etwas zu tun, macht Laravel so einfach und neulingfreundlich.

Arthur Tarasov
quelle
2

Eloquent ORM eignet sich am besten für die Arbeit mit weniger Daten in einer bestimmten Tabelle. Auf der anderen Seite benötigt der Abfrage-Generator weniger Zeit, um zahlreiche Daten in einer oder mehreren Tabellen schneller zu verarbeiten als Eloquent ORM.

In meinem Fall verwende ich ELoquent ORM in einer Anwendung mit Tabellen, die weniger als 17500 Einträge enthalten. Wann immer ich davon ausgehe, dass die Tabelle mehr als 17500 Einträge enthalten wird, ist der Abfrage-Generator der beste.

Außerdem bevorzuge ich in Anwendungen mit Unterabfragen den Abfrage-Generator gegenüber ELoquent ORM.

Patrick N.
quelle
2

Es gibt viele verschiedene zwischen ihnen

  1. Die Builder-Abfrage ist viel schneller als ORM, das Sie per Debugger testen. Hier erfahren Sie, wie Sie https://scotch.io/tutorials/debugging-queries-in-laravel testen können .
  2. Builder fragt weniger Zeit für die Ausführung ab, wenn Sie mit großen Datenmengen arbeiten, z. B. wenn Ihre Datenbank mehr als 1.00.000 als ORM enthält.
  3. Die Builder-Abfrage eignet sich am besten für große Datenmengen. Orm eignet sich am besten für die Arbeit mit Relationen, da es viele Beziehungsmethoden zum Definieren der Beziehung zwischen Tabellen bietet.
  4. Builder-Abfrage verwendet Join von SQL, aber Orm verwendet Relation, um 2 Tabellen oder mehr Tabellen zu bearbeiten.
Nitesh Mangla
quelle
1

Ich verwende gerne den Abfrage-Generator, wenn ich komplexe Abfragen aus einer Datenbank erstelle, weil sie einfach zu verwenden scheinen. Für die Arbeit mit einem einzigen Tisch mag ich beredt.

HENG Vongkol
quelle