Expertise zu Tabellen-Design

Tommi

Datenbank-Guru
Beiträge
293
Hallo zusammen,

ich habe in einem Projekt eine Tabelle, die umgebaut werden muss.
Ich hätte gerne ein paar Ideen gesammelt. Manchmal sehe ich den Wald vor lauter Bäumen nicht und hätte ganz gerne ein paar Anregungen und Lösungs-Ansätze von euch.
Ich gebe euch auch bewusst nur die Informationen, die ich zu Beginn an zu dieser Tabelle hatte.

Folgendes:
Die Tabelle ist eine Ergebnis-Tabelle eines Berechnungs-Vorganges.
Es gibt eine laufende ID (IDENTITY), einen ausführenden User, eine Kategorie-Spalte und eine Spalte des Berechnungs-Ergebnisses.
Zusätzlich gibt es 5 Spalten (Identifier1 bis Identifier5), in denen verschiedene Informationen zu den jeweiligen Kategorien eingetragen werden. Es gibt etwa 12 Kategorien. Welche Werte in die 5 Spalten geschrieben werden bzw. ob überhaupt Werte eingetragen werden, hängt von der Kategorie ab.
Die Identifier-Spalten sind alle als varchar-Felder angelegt.
Klar ist aber, dass in Identifier1, Identifier2 und Identifier5 immer eine Datum eingetragen wird.
Identfier3 ist bisher immer mit einer Währungs-Angabe (USD, EUR etc.) gefüllt.
Identifier4 ist aktuell leer.

Aufgabe ist es, die Performance von Lese- und Schreibvorgängen zu erhöhen.
Die Anzahl der Zeilen beträgt aktuell ca. 15 Mio. Datensätze. An einem Tag wird mindestens ein Berechnungslauf durchgeführt, es können aber auch bis zu 5 werden.
Jeder Berechnungs-Durchlauf erzeugt etwa 100.000 bis 150.000 Datensätze.

Mehr Informationen habe ich aktuell auch nicht.

Ich freue mich auf eure Beiträge.

Schon einmal vielen Dank und viele Grüße,
Tommi
 
Werbung:
Aufgabe ist es, die Performance von Lese- und Schreibvorgängen zu erhöhen.

Schreibvorgänge zu beschleunigen ist komplex. Da wäre z.B. zu prüfen, ob ungenutze Indexe mitgeschleift werden und ob die Updates/Insert in einer Transaktion oder in jeweils einzelnen erfolgen. Für Abfragen ist es IMMER gut, in's EXPLAIN zu schauen.
 
Also mich stört der ganze Aufbau, vor allem:
1) Du hast nach einem Berechnungslauf (ca. 1 bis 5 mal am Tag) 100-150k Ergebnis-Datensätze. Zumindest der Ausführende Benutzer ist vermutlich immer gleich, eventuell kommen noch weitere Metadaten die den "ganzen" Berechnungslauf betreffen.

2) Es gibt nur 12 Kategorien und 5 "Identifier", gehört das irgendwie zusammen und läßt sich das vielleicht auslagern?

3) Datum als VARCHAR() zu speichern ist mir zu wieder, auch wenn es vielleicht erstmal praktikabel ist. Mein DMS speichert Datum als Integer in Tagen seit 1900 +/- irgendwas, das mag mich etwas beeinflussen.

Das alles dürfte aber wenig negative Auswirkungen auf die Schreibperformance haben, die Leseperformance hängt von dem Abfragen und Indexen ab. Wenn die Indexe das Schreiben verlangsammen lohnt es vielleicht den Index vor dem Berechnungslauf zu löschen und im Anschluss neu zu erzeugen.
 
Die Aufgabenstellung ist etwas diffus. Wie sehen die Zeiten jetzt aus und was ist das Ziel?
Wie sehen die Transaktionen aus? Nach jedem Insert ein Commit oder alles in einem Rutsch?
 
Hallo zusammen,

vielen dank für eure Antworten, war sehr hilfreich:

@akretschmer: sehr guter Hinweis - ungenutzte Indexe bei Schreib-Performance - ganz herzlichen Dank

@ukulele: habe in die gleiche Richtung gedacht, auslagern und bloß kein Datum in Textformat ablegen. Auch dir herzlichen Dank, da du damit bestätigt hast, dass ich nicht völlig quer gedacht habe.
Auch ein guter Hinweis: Neuerstellen eines Index statt insert oder reorg.

@drdimitri: Die aktuellen Zeiten sind zum Thema gesamt erst einmal nicht interessant. Ging ja um allgemeine Ideen zur Performance-Verbesserung.
Interessant ist deine Frage zum Thema
Nach jedem Insert ein Commit oder alles in einem Rutsch
.

Zum Zeitpunkt meines Beitrages hatte ich nur unwesentlich mehr Informationen, als ich oben angegeben habe.
Inzwischen ist klar, dass ein Service zwischen Datenbank und Applikation zwischengelagert werden soll.
Dieser Service erweist sich als sehr langsam. Die Datenbankzugriffe an sich sind schnell und können auch nicht weiter optimmiert werden (ok, bessere HW wäre noch möglich, ist aber nicht gewünscht).
Der Service erzeugt aber einen Time-Overhead von 60% an der Gesamt-Zeit.

Ergebnis ist also, dass der Service langsam ist und nicht die Datenbank oder die Abfrage.
Um alle Ergebnisse darzustellen benötigt der Dienst (Datenabfrage + Erstellen eines datenobjekts im Speicher + Darstellung in einem Grid) 12 Sekunden, 5 Sekunden davon die Datenbank.
Abgefragt werden dabei ca. 60.000 Datensätze aus 5 Tabellen. Die größte Datenmenge in einer Tabelle (die oben genannte) umfasst 40.000 Zeilen, die in 3,5 Sec. zurückgegeben werden.

Das Dicke kommt aber noch: der Service soll die Daten über eine StoredProc in die Datenbank schreiben, wobei die einzutragenden Daten per Parameter übergeben werden sollen.
Bedeutet: Aufruf der Prozedur für jede einzutragende Zeile! (siehe oben: bei jedem Rechnungslauf ca. 150.000 Datensätze). (@drdimitri: so viel zu deiner Frage :))
Das ist noch nicht implementiert, aber ich bin auf die Gesamt-Zeiten gespannt.

Das beschäftigt mich grade noch.

Aber euch allen noch einmal ganz herzlichen Dank für eure Beiträge.

Viele Grüße,
Thommi.
 
Inzwischen ist klar, dass ein Service zwischen Datenbank und Applikation zwischengelagert werden soll.
Hmm klingt schwer danach, dass Javaentwickler ihr Unwesen treiben.

Wenn ihr unbedingt Batches über einen Service betreiben wollt, muss das ein Listenservice sein, der auch parallel aufgerufen werden kann.
Mit Einzelsatzverarbeitung kommt ihr nicht weit.

Alternative wär ein Messageingsystem dazwischen, dass die Anfragen asynchron verarbeitet - dann muss zumindest der Consumer nicht warten.

Idealerweise Export der Dateien als File und Import in die DB in einem echten Batch.
 
Werbung:
Wäre es denkbar den "Berechnungslauf" der jetzt als Service arbeitet (verstehe ich richtig oder?) komplett innerhalb der DB abzuwickeln?
 
Zurück
Oben