Laden...

Hohe TTFB Zeit fixen - Datenbank Zugriff zu langsam?

Erstellt von Sebastian1989101 vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.420 Views
Sebastian1989101 Themenstarter:in
241 Beiträge seit 2010
vor 4 Jahren
Hohe TTFB Zeit fixen - Datenbank Zugriff zu langsam?

Bei einem neuen ASP Core 3.1 Projekt habe ich, lokal, eine TTFB von in etwa 20ms. Meine Webseite, welche inzwischen auch mit ASP Core 3.1 läuft wird jedoch gefühlt immer langsamer. Hier kommt es immer häufiger vor dass die TTFB bei ~3sec liegt. Wenn ich das Laden der Daten aus der Datenbank entferne, liegt die TTFB bei "nur" noch ~200ms. Nicht ideal, aber ein Anfang. Nun wäre aber die frage, wie implementiert man dies am besten, dass die Daten der Datenbank quasi nachdem die Seite geladen wurde erst geladen werden? Vor einigen Jahre noch hätte ich dies vermutlich mit ajax gemacht, aber ist das wirklich noch up2date oder gibt es inzwischen bessere Methoden? Da ich nur selten an Web und noch viel seltener an ASP Core arbeite, bin ich da derzeit wohl auch nicht auf den aktuellsten Stand.

Daher die Frage an euch: Würde man dies noch mit ajax lösen oder gibt es inzwischen "bessere" Methoden dafür die Daten erst nach dem laden der Seite nachzuladen? Mal ganz davon abgesehen dass ich parallel auch die Datenbank verbessern sollte.

WAGO Kontakttechnik GmbH & Co. KG / Software Notion
Softwareentwicklung

C# .NET with WPF, ASP, Xamarin and Unity
Personal Blog: Development Blog

T
2.219 Beiträge seit 2008
vor 4 Jahren

Stellt sich die Frage was genau nun lange dauert.
Das laden der DAten aus der DB oder die Übertragung.
Wie lädst du die Daten ein, welche DAtenmengen hast du dort zu laden.

Auch wäre die Frage ob als letzte Lösung auch Caching der Daten in Frage kommt oder sind die Datenmengen ggf. nicht cachbar?
Ich würde im letzten Schritt, wenn die DB Abfrage und Struktur nicht mehr optimierbar ist, die Daten im Web Cache befristet vorhalten, wenn sich diese nicht häufig ändern.

Gibt viele Lösungsmöglichkeiten, hier müsstest du aber erst einmal schauen was die Ursache für eine Zeit von mehr als 2 Sek. ist.
Wenn die DB auch bei dir lokal liegt, müsstest du mal prüfen ob diese auch optimal arbeiten kann.
Je nach DB sind hier noch Optimierungsmöglichkeiten durch die Konfiguration und durch Dateihandling möglich.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

Sebastian1989101 Themenstarter:in
241 Beiträge seit 2010
vor 4 Jahren

Aktuell handelt es sich bei der DB um ein MS-SQL Server. Die Datenbank selbst ist ca. 1GB derzeit groß und wächst munter weiter (hier werden u.a. Changelogs für meine Apps von Apple und Google abgelegt sowie eine Kopie des AppStore-Eintrages inkl. derer Bilder). Für das Entwickeln habe ich eine 1:1 Kopie der Datenbank lokal mit dummy Daten, hier ist die DB aber nur ~320MB groß zur Zeit.

Die Daten können, in den meisten Teilen, Problemlos in ein Cache wandern und müssten nicht immer aus der DB kommen. Bei der Changelog Tabelle sowie den AppStore-Einträgen würde es reichen wenn der Cache auf täglicher Basis erneuert wird. Bei der In-App-Kauf Verifizierung hingegen sollte im Idealfall kein Caching zum Einsatz kommen - dies ist aber die gleiche Datenbank, nur andere Tabellen natürlich. Kann man sowas mit dem EntityFramework abbilden dass die Caching-Strategie an der Tabelle hängt?

Aber ich denke es wäre, auch wenn die Datenbank optimiert ist, besser wenn die Daten nach dem laden der Seite nachladen würden. Daher die frage ob für sowas immer noch ajax aktuell ist oder bessere Methoden existieren.

WAGO Kontakttechnik GmbH & Co. KG / Software Notion
Softwareentwicklung

C# .NET with WPF, ASP, Xamarin and Unity
Personal Blog: Development Blog

T
2.219 Beiträge seit 2008
vor 4 Jahren

Die Bilder werden hoffentlich außerhalb der DB gespeichert und du hast nur Verweise auf die Bilder in der DB.
Gerade Dateien sollten nicht in der DB gespeichert werden, wenn es dafür keinen driftigen Grund gibt.
Die Bilder sollten direkt auf dem Webserver liegen, dann kann der Webserver diese bereits cachen.
Ebenfalls bläht man sich mit Dateien direkt in der DB die Datenbank nur unnötig auf, was ab einer bestimmten Mengen einfach Overhead ist.

Du kannst zwar den Ansatz nehmen und die Dateien nachladen, müsstest dann aber z.B. die Weboberfläche für den Client mit HTML/JS umsetzen und den Server nur noch per JS mit z.B. Web API antriggern um die Daten zu laden.
Gängige Frameworks dafür sind z.B. Angular, React etc.
Anleitungen dafür findest du bei Google 😃

Dies löst aber dein grundlegendes Problem mit langen Ladezeiten nicht.
Du kaschierst damit nur das eigentliche Problem.
Im ersten Schritt würde ich die Ursache ergründen und beseitigen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.806 Beiträge seit 2008
vor 4 Jahren

AJAX ist ein Zusammenspiel verschiedener Protokolle bzw. Datenübertragungswegen (Ajax (Programmierung)). Es ist nicht auf Technologien bezogen oder schränkt diese ein. Daher kann dieses Paradigma grundlegend nicht veralten.
Die Grundidee in modernen Zügen würde man heute als SPA oder PWA bezeichnen.
Das würde jedoch eine komplettes Umschreiben bedeuten.

Letzten Endes wäre das jedoch auch nur eine Verschleierung des Performance Problems.
Ohne, dass Du genau identifizierst, was für die langsame Antwort verantwortlich ist, wirst Du nicht sauber aus der Sache kommen.
Du kannst rumpuzzlen und kaschieren; das Problem bleibt.

  • Was ist für die Performanceverluste verantwortlich?
  • Wo genau bleibt die Zeit liegen?
  • Was sagt ein Profiler?
  • Datenbank normalisiert?
  • Index funktioniert?

Die Daten können, in den meisten Teilen, Problemlos in ein Cache wandern und müssten nicht immer aus der DB kommen.

Dieser Grundgedanke ist Schuld (im Allgemeinen), dass sich viele Applikationen später nicht mehr so einfach migrieren lassen.
Auch zeigt die Frage im Zusammenhang mit EF, dass Du offenbar die Grundfunktionsweise vom EF nicht soooo ganz verinnerlicht hast; denn das Context Attachments von Entities ist für alles ausgelegt, aber nicht um diese über 832434 Threads zu Cachen und zu sharen 😃
Daher: lass das sein - und löse erst mal das Grundproblem.

Ich vermute, dass das Grundproblem entweder im Datenbank-Code, im Datenbank-Setup oder in beidem liegt.
Gerade die falsche Handhabung vom EF und fehlende Indexe kosten viel Performance.
Gibt viele EF Anfänger-Tutorials, wo solche Punkte behandelt werden; evtl. passt das hier.

PS: mit TTFB hat das nicht wirklich was im eigentlichen Sinne zutun 😉

Sebastian1989101 Themenstarter:in
241 Beiträge seit 2010
vor 4 Jahren

@T-Virus: Aktuell sind die Bilder tatsächlich in der Datenbank statt im Filesystem. Sicher auch noch eins der Dinge, die ich noch dringend ändern muss. Ich hatte die Bilder bisher als base64 string abgespeichert da ich die Daten so erhielt und nicht aufbereiten musste. Ursprünglich war das ganze auch nur für eine Handvoll Einträge gedacht, dass es nun einige hundert sind, rächt sich da natürlich.

Ich denke ich werde neben der DB Optimierung mir dann auch nochmal Angular und React ein wenig ansehen.

Die Ursache habe ich glaube gerade auch gefunden. Das Projekt ist schon 4 Jahre alt und ich weiß nicht was mich damals bei der ersten Version geritten hat, aber ein .ToList() auf das DbSet sorgt natürlich dafür dass immer alle geladen werden, unpraktisch erst danach das sortieren und filtern zu machen obwohl die DB das viel besser könnte - darum brachte der DB Index natürlich auch nichts. Aber manchmal sieht man den Wald vor lauter Bäumen wohl nicht.

@Abt: Ist halt manchmal auch eine Aufwand/Nutzen frage. Aber ja, die schöne Lösung ist immer das Problem zu identifizieren und zu lösen - ist manchmal aber gar nicht so einfach ohne tiefere Kenntnisse in der Technologie wobei das Problem hier, wie bei der Antwort an T-Virus bereits erwähnt, eher auf Blindheit oder damalige Unwissenheit zurückzuführen ist.

Über TTFB fiel mir dieses Fehlverhalten halt zunächst auf. Auch wenn sich nun zeigt dass das Kernproblem die Handhabung der Datenbank ist. Wobei selbst ohne Datenbank ein TTFB Wert von 200ms finde ich echt schwierig, vermutlich ist also noch etwas im argen.

WAGO Kontakttechnik GmbH & Co. KG / Software Notion
Softwareentwicklung

C# .NET with WPF, ASP, Xamarin and Unity
Personal Blog: Development Blog