Laden...

Für Read-Performance statt FK-Referenz auf "Sub"-Table Daten in Spalte serialisieren?

Erstellt von M@TUK vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.188 Views
M
M@TUK Themenstarter:in
402 Beiträge seit 2005
vor 11 Jahren
Für Read-Performance statt FK-Referenz auf "Sub"-Table Daten in Spalte serialisieren?

verwendetes Datenbanksystem: MSSQL 2008 r2

Hi...

ich hab ein Performance-Problem bei einem Legacy-System (Webapplication)

Es sind hier Daten tief "verschachtelt" und diese müssten extrem performant aus der DB geladen werden.

Struktur:

Artikel
Artikel-Features
Artikel-Beschreibungen
Artikel-Bilder => Datei
Artikel-Dateien => Datei
Artikel-Eigenschaften

Es wird das EF 5 mit CodeFirst verwendet.

Wenn nun viele Artikel mit allen Subdaten geladen werden sollen kommt da eine enorme Datenmenge zusammen...

Soviel ich vom generierten SQL-Statement des EF rauslesen konnte würde bei 100 Artikeln mit jeweils 5 Datensätze in jedem Sub-Table durch das EF (durch "Include(x).Include(y).Include(z)...")

100 * 5 * 5 * 5 * 5 * 5 = 312500

Datenzeilen geladen werden.

Noch schlimmer wenn mehr Subdaten enthalten wären...

Layzyloading ist leider keine Option weil die Daten alle sofort zur Verfügung stehen müssen.

Rein von der Datenstruktur her wäre natürlich eine noSQL-Datenbank wie z.b. RavenDB oder MongoDb dafür perfekt geeignet, aber der "Umbau" des Systems würde momentan viel zu lange dauern.

Ich hab mir nun überlegt ob es nicht möglich wäre die einzelnen Sub-Daten in zusätzliche Spalten zu serialisieren und nach dem Laden aus der Datenbank zu deserialisieren und die Objekte in die entsprechenden Listen zu hängen.

Wäre das eine gute Idee? Gibt's andere Best Practices um solche Strukturen besser, schneller aus der DB zu laden?

Thx

F
10.010 Beiträge seit 2004
vor 11 Jahren

300.000 Datensätze aus einer SqlServerDB zu lesen sollte eigentlich nicht soo lange dauern.
Beschreibe erst einmal welche Zeiten Du erwartest und welche Du hast.

Dann wäre noch interessant ob die DB mehr geschrieben oder gelesen wird.
Indizes richtig gesetzt?

16.842 Beiträge seit 2008
vor 11 Jahren

Ich kann mir sehr gut vorstellen, dass da so lange dauert.
Das Problem ist einfach der Serializer vom EF, der unheimlich unperformant ist. Bei einfachen Writes wird pro Entity um die 40 Objekte erstellt, das wird beim Read nicht arg viel anders sein (Proxies und Co).

Das EF ist bequem aber leider nicht performant. Daher nimmt man auch immer mehr Abstand in der Webwelt davon. Das spiegelt sich auch in den MsDN Foren wieder.

742 Beiträge seit 2005
vor 11 Jahren

Ein paar Ideen:

  1. Kann es schneller sein, wenn du z.B. die IDs aller Artikel eermittelst und dann jeden Artikel noch mal einzeln abfrägst.

  2. Ich würde mich genau fragen wieso du alle Informationen für 100Artikel gleichzeitig brauchst.

  3. Wenn alles nix hilft musst du Denormalisieren oder eine für Lesezugriffe optimierte Tabelle aufbauen. Das muss ja nicht Mongo-DB sein.

M
M@TUK Themenstarter:in
402 Beiträge seit 2005
vor 11 Jahren

Hi...

vielen Dank für die Antworten,

die 100 Artikel waren eigentlich nur beispielhaft,
es könnten auch 200, 500, oder 2000 sein, was natürlich das Ergebnis noch extremer aufbläht.

Ich benötige alle Daten weil mit dem Ergebnis bzw. den darin enthaltenen SubDaten weitere Operationen gestartet werden.

Ich glaube aber dass es nicht unbedingt direkt mit dem EF zusammenhängt. Der Select der an den SQL-Server gesendet wird verursacht dort teilweise einen SUSPENDED Status, also geh ich mal davon aus, dass der Query nicht "optimal" ist.

Ich hab schon teilweise versucht Teile der SubDaten über einen eigenen Query zu laden und diese dann in einer Schleife zuzuweisen.
Das hat die Performance etwas verbessert und die SUSPENDED-Stati am SQL-Server etwas reduziert. Nur finde ich das nicht ganz sauber.

Vielleicht werde ich aber mal probieren diese Abfragen direkt mit ADO.net zu machen ohne dem ganzen ORM-Zeugs. Wenns Abhilfe schafft perfekt, wenn nicht muss ich mir was anderes einfallen lassen.... 😦

742 Beiträge seit 2005
vor 11 Jahren

Ich bezweifel noch ein bisschen, dass du in einem Online-Shop zeitkritisch 200 Artikel inklusive Details anzeigen musst. Wie sieht denn dein Szenario genau aus?

F
115 Beiträge seit 2012
vor 11 Jahren

Hi,

schonmal nach den db-Statistiken geschaut? Wenn die nicht die aktuelle Datenlage wiederpsiegeln entscheidet sich der Optimizer gerne für nicht so tolle Zugriffspfade. Um dazu was sagen zu können braucht man natürlich die kompletten DDLs, Statisiken und Explains der SQLs.

Ich tät mal update Statistics und ggf. des MSSQL Equivalent von reorg machen.

Allerdings bezweifle ich, dass man mich generiertem SQL aus dem EF gute Chancen auf performante db-Abfragen hat.

Bei vergleichsweise kleinen Datenmengen (wie einer Artikeldatenbank) kann man sicherlich auch versuchen an der Datenbank was zu optimieren. Mit genügend freiem RAM kann man die IOs sicherlich auf 0 senken, die oft das Problem darstellen.

Gruß
f_igy