Laden...

Schlechte Performance bei MySQL-Datenbankzugriff

Erstellt von tequila slammer vor 13 Jahren Letzter Beitrag vor 13 Jahren 986 Views
T
tequila slammer Themenstarter:in
253 Beiträge seit 2006
vor 13 Jahren
Schlechte Performance bei MySQL-Datenbankzugriff

Ich habe eine Frage zur Performance bei der Objekt-Erstellung nach folgendem Schema.

Meine Klassen haben eine statische Methode, die ein Objekt erstellt. Einige geben auch Sammlungen von Objekten zurück. Diese Sammlungen fragen nur die Id ab und rufen immer wieder die GetMyObject-Methode auf. Ich versuche damit nach dem DRY-Prinzip zu arbeiten. Nun stelle ich fest, dass das Abrufen der Sammlung recht lange (5-6Sek) dauert obwohl es sich gerade mal um 900 Datensätze in einer MySQL Datenbank handelt.


public static MyObject GetMyObject(int dataBaseObjectId)
{
   var myObject = new MyObject();
   //Datenbankabfragen/ Eigenschaften setzen
   return myObject;
}


public static MyObjectCollection GetMyObjects()
{
   var myObjectCol = new MyObjectCollection();
   //Datenbankabfrageerstellung usw.
   while(reader.read())
   {
      myObjectCol.Add(GetMyObject((int)reader["Id"]));
   }

   return myObjectCol;
}

2.891 Beiträge seit 2004
vor 13 Jahren

Vielleicht ein typisches Select N+1-Problem!?

T
50 Beiträge seit 2010
vor 13 Jahren

Also ich würde mal sagen, dass Du für jedes Objekt in Deiner Liste eine eigenen Datenbankabfrage machst. Das kann nur wenig performant sein. Ich empfehle Dir folgenden Aufbau, der auch dem DRY-Prinzip folgen sollte:

public static MyObject GetMyObject(int id)
{
    // Datenbankabfrage
   if(reader.read())
   {
        return FillObject(reader);
   }
}

public static MyObjectCollection GetMyObjects()
{
   var myObjectCol = new MyObjectCollection();
   //Datenbankabfrageerstellung usw.
   while(reader.read())
   {
      myObjectCol.Add(FillObject(reader));
   }

   return myObjectCol;
}

private static MyObject FillObject(MySqlDataReader reader)
{
   var myObject = new MyObject();
   //Eigenschaften setzen
   return myObject;
}
T
tequila slammer Themenstarter:in
253 Beiträge seit 2006
vor 13 Jahren

Danke für den Link. Darin wird mein Problem gut erklärt. Ich werde mal teebeast Vorschlag implementieren und dann mal schauen.

Wie löst ihr das, wenn mein Objekt noch unter Objekte enthält? Diese werden auch via einem eigenen Select Befehl erstellt. Hier würde ich nur ungern mit einem join im SQL Statement arbeiten, damit ich die Objekterstellung in der Klasse zum Objekt behalte.

C
2.121 Beiträge seit 2010
vor 13 Jahren

Um dich zu beruhigen, mit dem wiederholten Aufruf der selben Abfrage für die Tabelle machst du ja auch einen gnadenlosen "repeat yourself" Aufruf, wenn du den eliminierst bist du dem DRY Prinzip deswegen kein bisschen untreu 😉

Objektorientierung und die strenge Kapselung ist was schönes, aber bei Datenbanken nur bedingt brauchbar. Da holt man sich lieber alles in einem Aufwasch. Warum, das hast du ja selbst schon rausgefunden. Die DB muss in deinem Fall 900 mal eine Abfrage parsen, im Index suchen, Verbindungen öffnen und schließen ... oder sie macht das alles nur ein einziges Mal.

Die Unterobjekte würd ich daher auch in einer einzigen Abfrage holen, die sich auf die IDs der eigentlichen Objekte bezieht. Die Erstellung des Objekts aus diesen Daten kann dann ja trotzdem in den Klassen bleiben wo sie hin gehört, nur die Datengrundlage kommt woanders her.
Wenn das Hauptobjekt alles lädt und dann die Datenzeilen an die Unterobjekte übergibt damit die sich daraus erstellen, mit sowas könnte ich durchaus leben solangs performant läuft.

T
tequila slammer Themenstarter:in
253 Beiträge seit 2006
vor 13 Jahren

Ich bin gerade am Umbauen. Nur das Hauptobjekt auf teebeasts Vorschlag zu ändern brachte keine spürbare Verbesserung.