Zum Inhalt springen

Datenbank-Engineering

Datenbank- & Eloquent-Engineering

Die Abfragearbeit hinter einer Laravel-Anwendung, die ihrem Schema entwachsen ist - N+1 beseitigen, Indizes aus echten Abfrageplänen, und Migrationen, die keine laufende Tabelle sperren.

Fast jede Laravel-Anwendung, die langsam wird, wird in der Datenbank langsam, und fast jede davon war in der Entwicklung in Ordnung. Eine Seite, die elf Abfragen gegen vierzig Zeilen ausführt, führt elf Abfragen gegen vier Millionen Zeilen genauso aus, und nur eines von beidem ist überlebbar.

Wohin die Zeit tatsächlich geht

Über die Projekte hinweg, die wir durchführen, gruppieren sich die Ursachen zu einer kurzen Liste.

Ein N+1, das nur in der Produktion auftaucht. Die Übersichtsseite lädt ihre Relation vorab. Die Detailseite nicht, weil sie immer nur einen Datensatz lädt – und dann verwendet jemand die Detail-Komponente in einer Schleife wieder. Die Abfragezahl geht von zwei auf zweihundert und nichts im Diff sieht falsch aus.

Eine Relation, die in einem Accessor geladen wird. getFullAddressAttribute() greift auf $this->country zu, der Accessor wird beim Serialisieren aufgerufen, und die Anwendung setzt eine Abfrage pro Zeile ab, während sie aussieht, als formatiere sie eine Zeichenkette.

Ein Index, der existiert und nicht benutzt wird. Eine Spalte in eine Funktion gewickelt, eine implizite Typumwandlung zwischen einer Zeichenkettenspalte und einem Integer-Parameter, ein führendes Platzhalterzeichen bei LIKE. Der Index ist da, EXPLAIN sagt, er wird nicht gelesen, und alle vertrauen dem Schema statt dem Abfrageplan.

Aggregation in PHP. Die Collection-Pipeline ist ausdrucksstark genug, dass ->get()->groupBy()->map() sich besser liest als das SQL, also werden hunderttausend Zeilen zu Modellen hydriert, um sechs Zahlen zu erzeugen.

Eine Migration, die eine laufende Tabelle gesperrt hat. Einen Index hinzufügen, eine Spalte mit Standardwert hinzufügen oder einen Spaltentyp ändern – auf einer Tabelle, die groß genug ist, dass die Sperre den Anfrage-Timeout überdauert. Das Deployment war erfolgreich; die Seite war unten.

Wie wir arbeiten

Zuerst messen, am echten System. Slow-Query-Logs, die Abfragezahl pro Endpunkt und EXPLAIN auf den Abfragen, die zählen. Kein Profiler auf einem Laptop mit einer befüllten Testdatenbank, der Ihnen verlässlich von einem Problem erzählt, das Sie nicht haben.

Die Ursache beheben, nicht das Symptom. Ein Cache vor einer schlechten Abfrage ist eine Art, die schlechte Abfrage seltener zu bezahlen. Manchmal ist das die richtige Entscheidung und wir sagen das; häufiger will die Abfrage einen Index, einen Join, oder zur Laufzeit gar nicht erst abgesetzt werden.

Die Korrektur dauerhaft machen. Lazy Loading außerhalb der Produktion abgeschaltet, damit das gerade entfernte N+1 nicht still wieder eingeführt werden kann. Eine Zusicherung auf die Abfragezahl für die Endpunkte, die zählen, damit eine künftig entfernte Vorab-Ladung einen Test scheitern lässt statt ein Support-Ticket auszulösen. Beides sind wenige Zeilen und sie machen den Unterschied zwischen einer Korrektur und einer Korrektur, die bleibt.

Schemaarbeit an einem System, das nicht stehenbleiben darf

Das meiste, worum wir gebeten werden, ist keine Abfrage, sondern eine Form: eine Statusspalte, die eine Statustabelle sein sollte, eine polymorphe Relation, die zwei Zeilen unmöglich beschränkbar gemacht hat, ein Auditlog, das ohne Aufbewahrungsregel wächst, eine Tabelle, die drei Aufgaben erfüllt, weil das Aufteilen vor zwei Jahren teuer schien.

Diese Arbeit passiert in Schritten, die einzeln sicher sind:

  1. Die neue Struktur neben der alten anlegen, ohne dass etwas sie liest.
  2. In Stapeln befüllen, auf einer Queue, mit einem Fortschritt, der ein Deployment übersteht.
  3. In beide schreiben, aus der alten lesen und abgleichen, bis der Unterschied null ist.
  4. Lesen umstellen. Warten. Dann aufhören, die alte zu beschreiben.
  5. Sie in einem eigenen Release löschen, sobald sie eine Woche lang niemand angefasst hat.

Das sind mehr Schritte als eine einzelne Migration, und es ist der Unterschied zwischen einer Schemaänderung und einer geplanten Ausfallzeit.

Was Sie bekommen

Ein Befunddokument, in dem jedes Problem auf die Abfrage oder die Migration zurückgeführt ist, die es verursacht, und nach Aufwand bemessen; die Korrekturen als prüfbare Pull Requests; die Indexänderungen als Migrationen, die bei Ihrem Datenvolumen sicher laufen; und die CI-Zusicherungen, die die Rückfälle stoppen.

Wo die Antwort strukturell statt eine Abfrageumschreibung ist, sagen die Befunde das und stellen beide Zahlen nebeneinander: was die Änderung kostet und was es kostet, sie im nächsten Jahr zu lassen. Das sollten Sie in der ersten Woche lesen und nicht in einem Abschlussgespräch hören.

Vor dem Start wollen die meisten zwei Dinge lesen: was eine sperrende Schemaänderung auf einer produktiven Tabelle kostet und worin sich MySQL und Postgres für eine Laravel-Anwendung tatsächlich unterscheiden. Stellt sich heraus, dass nicht die Abfrage langsam ist, sondern der Request-Pfad, ist Performance das Nachbarprojekt.

Umfang und Konditionen

Zusammenarbeit
Fester Umfang, schriftlich vereinbart, bevor die Arbeit beginnt. Kein Tagessatz gegen ein offenes Backlog.
Preis und Dauer
Beides wird je Projekt festgelegt, sobald der Umfang steht. Gemeinsam angeboten, bevor etwas gebaut wird.
Was wir von Ihnen brauchen
Eine Person, die entscheiden darf, und Zugang zu Ihrem Repository und Ticketsystem.
Nicht enthalten
Alles außerhalb des vereinbarten Umfangs. Es wird ein eigener Umfang statt eines Änderungsauftrags.
Kosten Dritter
Hosting, Lizenzen, API-Gebühren und SaaS-Abonnements schließen und zahlen Sie selbst.
Rechnungsstellung
Codefacture Yazılım A.Ş., Türkiye. EUR, USD oder GBP per Überweisung, ohne türkische Umsatzsteuer auf exportierte Leistungen.

Häufige Fragen

Ist das dasselbe wie Performance-Arbeit?
Überschneidend, aber nicht dasselbe. Performance und Skalierung umfasst den ganzen Anfragepfad - Caching, Queues, Worker, die Web-Schicht. Hier geht es speziell um die Datenbank, wo der größte Teil der Laravel-Langsamkeit sitzt, aber eben nicht alle. Wenn Sie nicht wissen, was von beidem Sie haben, sagt es das Audit.
Ersetzen Sie Eloquent durch rohes SQL?
Selten, und nie flächendeckend. Eloquent ist in den meisten langsamen Anwendungen nicht das Problem: wie es benutzt wird, schon. Wo ein Report wirklich nach einem Query Builder oder rohem SQL verlangt, sagen wir das - aber ein ORM zu ersetzen, um ein N+1 zu beheben, heißt eine Gewohnheit wie eine Architektur zu behandeln.
Können Sie an einer Datenbank arbeiten, die wir nicht kopieren dürfen?
Ja, und das ist häufig. Wir arbeiten mit Query-Logs, EXPLAIN-Ausgaben und einem Schema-Dump ohne Zeilen darin. Wo wir Datenformen statt Daten brauchen, genügt ein anonymisierter Ausschnitt.
Ändern Sie das Schema an einem laufenden System?
Nur mit schriftlichem Plan und einem Rückweg, und meist in mehr Schritten, als es aussieht: hinzufügen, in Stapeln befüllen, Lesen umstellen, Schreiben umstellen, löschen. Eine Migration, die nach einer Zeile aussieht, sind häufig fünf Deployments, wenn die Tabelle groß ist und die Anwendung nicht stehenbleiben darf.
Anrufen+1 848 272 7583WhatsApp+90 850 308 5436E-Mailinfo@codefacture.comKontaktseite