Leistungsprobleme mit EmberJS und Rails 4 API

8

Ich habe eine EmberJS-Anwendung, die von einer Rails-4-REST-API betrieben wird. Die Anwendung funktioniert so, wie sie ist, wird jedoch aufgrund der Art der ausgeführten Abfragen sehr träge.

Derzeit ist die API-Ausgabe wie folgt:

%Vor%

Das Problem tritt auf, wenn ein Benutzer viele Projekte mit vielen Builds hat, die zwischen ihnen aufgeteilt sind. EmberJS sucht derzeit nach builds key und stellt dann eine Anfrage an /builds?ids[]=1&ids[]=2 , was das gewünschte Verhalten ist.

Diese Frage könnte eine von zwei Lösungen haben.

  1. Aktualisieren Sie die Rails, um die build_ids effizienter zu laden
  2. Aktualisieren Sie EmberJS, um verschiedene Abfragen für Builds zu unterstützen

Option 1: Aktualisieren Sie die Rails

Ich habe verschiedene Lösungen für das eifrige Laden und das manuelle Ergreifen der IDs mit benutzerdefinierten Methoden auf dem Serializer ausprobiert. Beide Lösungen fügen viel zusätzlichen Code hinzu, den ich lieber nicht machen würde, und machen trotzdem individuelle Abfragen pro Projekt.

Standardmäßig verwendet rails auch SELECT * style-Abfragen, wenn has_many ausgeführt wird, und ich kann nicht herausfinden, wie dies auf der Serializer-Ebene überschrieben wird. Ich schrieb auch eine schreckliche Lösung, die das Ganze zu einer schnellen Abfrage brachte, aber es beinhaltete das Schreiben von Raw SQL, von dem ich weiß, dass es nicht die Rails-Methode ist und ich würde lieber keine so große komplexe untestable Abfrage wie den Standardbereich haben .

Option 2: Machen Sie Ember verschiedene Abfragen verwenden

Anstatt /builds?ids[]=1&ids[]=2 anzufordern, würde ich den Build-Schlüssel lieber nicht in das Projekt aufnehmen und eine Anfrage an /builds?project_id=1 stellen, wenn ich auf diese Variable in Ember zugreife. Ich denke, ich kann das manuell pro Feld durchführen, indem ich etwas Ähnliches benutze:

%Vor%

anstelle des aktuellen:

%Vor%

Es ist auch erwähnenswert, dass dies nicht nur für "Builds" gilt. Es gibt 4 andere Schlüssel auf dem Projektobjekt, die dasselbe tun, also 4 Abfragen pro Projekt.

    
Marc Qualie 09.04.2014, 21:27
quelle

2 Antworten

4

Haben Sie sichergestellt, dass Sie Ihrer Datenbank ordnungsgemäß Indizes hinzugefügt haben? Das Hinzufügen und Indexieren der Build-Tabelle in project_id wird es viel schneller arbeiten lassen.

Alternativ sollten Sie das Attribut links verwenden, um Ihre Datensätze zu laden.

%Vor%

Dies bedeutet, dass die Build-Tabelle nur abgefragt wird, wenn auf die Beziehungen zugegriffen wird.

    
alexspeller 14.04.2014 21:31
quelle
2

Dinge, die Sie ausprobieren können:

  • Stellen Sie sicher, dass Ihr Rails-Controller nur die Spalten auswählt, die für die JSON-Serialisierung benötigt werden.

  • Stellen Sie sicher, dass Sie Indizes für die Spalten haben, die in Ihren where- und join-Klauseln enthalten sind, es sei denn, die Spalte ist boolesch oder weist eine geringe Anzahl unterschiedlicher Werte auf. Stellen Sie immer sicher, dass Sie Indizes für Fremdschlüsselspalten haben.

  • Seien Sie sehr vorsichtig mit der Verwendung von ActiveRecord joins vs includes vs preload vs eager und references . Dieser Bereich ist mit Problemen behaftet, die Bereiche zusammensetzen, und subtile Dinge können die erzeugte SQL und die Anzahl der ausgegebenen Abfragen verändern und sogar die tatsächlichen Ergebnisse zurückgeben. Ich bemerkte Unterschiede in kleineren Punktveröffentlichungen von AR 4, was zu unterschiedlichen Abfrageergebnissen führte, weil die Join-Strategie AR wählen würde.

  • Oft möchten Sie die Anzahl der an die Datenbank ausgegebenen SQL reduzieren, aber das Verbinden von Tabellen ist nicht immer die beste Lösung. Sie müssen einen Benchmark erstellen und EXPLAIN verwenden, um zu sehen, was bei Ihren Abfragen besser funktioniert. Manchmal können Unterabfragen / Unterauswahlen effizienter sein.

  • Das Abfragen nach parent_id ist eine gute Option, wenn Sie Ember Data dazu bringen können, die Anfrage auf diese Weise auszuführen, da die Datenbank eine einfachere Abfrage enthält.

  • Sie könnten das Ember-Modell anstelle von Ember-Data verwenden, ich verwende es derzeit als viel einfacher und einfacher an meine Bedürfnisse anzupassen und unterstützt Multi-Fetch, um 1 + N-Anfrageprobleme zu vermeiden / p>

  • Sie können möglicherweise eingebettete Modelle oder seitengeladene Modelle verwenden, damit Ihr Server die Anzahl der Webanforderungen und die Anzahl der SQL-Abfragen reduzieren und das liefern kann, was der Client in einer Anforderung / einem SQL benötigt. Ember-Model unterstützt sowohl Embedded- als auch Side-Loaded-Modelle, so dass Ember-Data auch ehrgeiziger sein kann.

  • Obwohl aus Ihrer Frage hervorgeht, dass Ember-Data ein Multi-Fetch durchführt, stellen Sie sicher, dass Sie für diese IDs eine SQL IN-Klausel anstelle von separaten Abfragen verwenden.

  • Stellen Sie sicher, dass das SQL auf Ihrer Rails-Seite nicht in einem 1 + N-Muster aufgefächert ist. Die Verwendung der Optionen includes zum Bewirken des dynamischen Ladens von AR-Beziehungen kann dazu beitragen, 1 + N-Abfragen zu vermeiden, oder sie kann Modelle je nach den in Ihrer Antwort benötigten Ergebnissen unnötig laden.

  • Ich habe auch festgestellt, dass die Ruby JSON-Serializer-Bibliotheken nicht optimal sind. Ich habe ein Juwel ToJson erstellt, das die JSON-Serialisierung um ein Vielfaches gegenüber den bestehenden Lösungen beschleunigt. Sie können es versuchen und Benchmark für sich selbst.

Ich fand, dass ActiveRecord (einschließlich AR 4) nicht gut für mich funktionierte, und ich zog am Ende zu Sequel , weil es so war gab mir so viel mehr Kontrolle über Join-Typen, Join Bedingungen und Abfrage Zusammensetzung und taktische eifrig laden, und es war nur schneller, hat eine breitere Unterstützung für Standard-SQL-Funktionen und hervorragende Unterstützung für Postgres-Funktionen und Erweiterungen. Diese Dinge können einen großen Unterschied bei der Gestaltung Ihres Datenbankschemas und der Leistung und Art der Abfragen, die Sie erreichen können, bewirken.

Sequel und ToJson Ich kann ungefähr 30-50 mal mehr Anfragen bearbeiten als mit ActiveRecord + JBuilder für die meisten meiner Anfragen und in einigen Fällen sogar hundertmal besser als das, was ich mit AR erreicht habe (insbesondere creates / updates). Neben der Tatsache, dass Sequel Modelle aus der DB schneller instanziieren kann, hat es auch einen Postgres-Streaming-Adapter, der es für große Ergebnisse noch schneller macht.

Wenn Sie Ihre Datenzugriffs- / ORM-Schicht und JSON-Serialisierung ändern, können Sie eine 30- bis 50-fach schnellere Leistung erzielen oder alternativ 30 bis 50 weniger Server für die gleiche Last verwalten. Es ist nichts zu verachten.

    
Andrew Hacking 21.05.2014 09:03
quelle