Ich habe folgendes Problem:
Ich will eine Datenbank zum testen mit 100Mio Zeilen füllen, und das dauert mir zu lange. Mit Hilfe eines kleinen Javaprogrammes per JDBC und mit Hilfe eines Prepared Statements werden die Zeilen zugefügt.
Ich habe folgende Tests gemacht:
DB auf kleinem Server:
CPU lokal <5%, auf dem Server <25%, speicher überall massig frei, Netzwerk ca 1%
Ergebnis: ca. 250 Zeilen/Sek
DB auf dickem Server:
CPU lokal <5%, auf dem Server <2%, speicher überall massig frei, Netzwerk ca 1%
Ergebnis: ca. 250 Zeilen/Sek
DB auf Localhost:
CPU ca 40%
Ergebnis: ca. 1200 Zeilen/Sek
Es ist dabei nichts sonderlich ausgelastet, was bremst also letztendlich die Aktion?
sind das INSERT-Befehle, falls ja, jeder als eine TX?
falls INSERT: warum nicht COPY?
falls INSERT: auch die kann man unterschiedlich schreiben, es gibt auch Multi-Row-Insert.
gibt es Indexe, andere Constraints?
Plattenaufteilung: hast Du Indexe und Daten getrennt?
Bedenke, je nach der Art wie Du das einspielst ist das TX-Log zu schreiben, fsync zu machen etc. Faktoren, die die Geschwindigkeit beeinflussen, gibt es viele. Zu erraten, was bei Dir abläuft, fällt wegens Reparaturarbeiten an /dev/glaskugel derzeit aber schwer.
Das sind ja alles nette Tipps, aber es ist leider nicht eine Spekulation dabei, was der Flaschenhals sein könnte. Wenn Ihr über Indizes und Transaktionen redet, dann redet ihr über Rechenleistung, Speicher und Geschwindigkeit im Netzwerk. All das sind bei mir freie Ressourcen. Ein Flaschenhals hat die Eigenschaft unumgänglich und zu 100% ausgelastet zu sein. Wenn also während der Aktion einer der rechner zu 100% ausgelastet ist, dann bin ich zufrieden, auch wenn es eine Woche dauert. Mir ist klar dass DB-Experten dass Ergebnis dann noch optimieren könnten, daber darum gehts mir nicht. Ich finde es auch interessant dass der kleine Server stärker ausgelastet ist als der dicke, aber beide exakt gleichlang brauchen. Ich habe vermutet, dass es vielleicht im Protokoll irgendwelche Wartezeiten gibt, die man sozusagen nicht minimieren kann. Und von diesem Thread habe ich mir Wissen oder Spekulationen erhofft, was nun den Flaschenhals betrifft und nicht eine allgemeine Optimierung. Mir ist klar dass das hier keiner Analysieren kann, aber vielleicht hat ja jemand eine Idee, nach was ich schauen könnte…
Wir haben Dir, aus der ferne und resultierend aus den wenigen Dingen, die Du uns sagtest, mögliche Probleme Dir aufgezeigt.
Und von diesem Thread habe ich mir Wissen oder Spekulationen erhofft, was nun den Flaschenhals betrifft und nicht eine allgemeine Optimierung. Mir ist klar dass das hier keiner Analysieren kann, aber vielleicht hat ja jemand eine Idee, nach was ich schauen könnte…
Dir sollte bewußt sein, daß das ‘Gesamtpaket’ stimmen muß. Wenn Du remote über Netz von einem Rechner auf den anderen via JDBC Daten pumpen willst, dann gehören zu diesem Gesamtpaket u.a. beide Platten der beteiligten Rechner, beide CPUs, beide RAMs, die Konfiguration des PG-Servers, die Art und Weise, wie die Daten kommen (einzelne Inserts, mit/ohne BEGIN/COMMIT, COPY, Multiline-Insert, …), Netzwerkverbindung (Datenrate, Latenz, …), Implementierung des Protokollstacks (beteiligte OS-Versionen), JDBC-Treiber und und und. Jede einzelne dieser eigentlich schon vorher genannten Komponenten kann optimiert werden, denn er kann auch der Flaschenhals sein.
Btw.: Massen-Inserts über High-Level-Schnittstellen abzuwickeln zu wollen ist schon mal nicht ganz zu Ende gedacht von Dir. Und die von ads und mir gestellten Fragen hast Du auch nicht beantwortet.
Gegen passende Bezahlung kann ich Dir gerne das auch noch mal in schön formulieren.
@andreas
Danke nochmal für dein Engagement, aber wir reden aneinander vorbei. Nochmal: Ich habe nur ein kurzes Programm geschrieben um die DB ordentlich zu füllen. Das wird genau einmal laufen. Es ist nicht notwendig es irgendwie zu optimieren. Es ist mir Wurst mit welcher Methode ich Zeilen zufüge, ob es schnellere gibt und auch wieviel Geld ich nun zahlen müsste, damit jemand das optimiert- das ist schlichtweg unnötig (Um mal eine Frage zu beantworten: Ich benutze bewusst keine TX, also wird wohl jede Zeile einzeln zugefügt, denke ich.). Meine Frage ist ganz einfach: Warum ist der Computer nicht voll ausgelastet? Wenn ich das auf localhost ohne Netzwerk mache, und der Rechner nur zu knapp 40% ausgelastet ist (und andere mir bekannte Resccourcen ebenfalls frei sind), dann entscheidet sich der Rechner mahr als die hälfte der Zeit zu warten und nichts zu tun (Die Zeit geht übrigens NICHT dafür drauf wie ihr erwähntet logs zu schreiben, von JDBC in etwas natives zu wandeln etc).
NOCHMAL GANZ KLAR: Ich beschwere mich nicht dass es zu langsam geht und möchte gerne wissen wie es schneller ginge, ich beschwere mich dass der Computer absolut gar nix tut zu einem Zeitpunkt an dem er von mir eine Aufgabe bekommen hat. Diese Zeit verschwendet er definitiv nicht mit Protokolltransfers und diversen Widrigkeiten meiner schlechten Implementierung, er wartet einfach!
DIE FRAGE IST: Worauf wartet er? Definitiv nicht auf irgendeine Form von Berechnung, denn er müsste ja selber rechnen. Worauf dann? Wenn ich die reinen Daten/Zeile sehr, sehr großzügig auf 1KB aufrunde und er 1000Zeilen /Sek schafft, dann ist das ca 1MB/sek und ich brauch wohl kaum zu erwähnen welche Geschwindigkeiten Festplatten/Speicher und die Sie verbindenden Kanäle heute übertragen können. Das scheidet für mich auch aus. Netzwerk fällt bei localhost auch raus. Was macht er denn sonst ausser rechnen, schreiben, verschicken?
Er macht genau das: rechnen, schreiben, verschicken. Er berechnet z.B. Indexe, er schreibt den Datensatz, er schreibt den Index, er verschickt ein COMMIT nach jedem Insert, dies bewirkt ein physisches schreiben des Datensatzes, er schreibt in sein Transaction Log, welches woanders ist als das Datenfile (aber selbe Platte vermutlich). Er schreibt also mind. 3 Dateien: eigentliche Tabelle, Index-file, Transaction Log. Das sind ohne Ende Kopfbewegungen. Als Hausaufgabe kannst Du ja mal ausrechnen, wie viele Seeks so ein Kopf bei, sagen wir mal, 5ms pro Bewegung, in einer Sekunde schaffen kann. Zwischendurch rechnet er an den Indexen rum, prüft andere Constraints, checkt die Daten, … wenn Du mehr Transaktionen/Sekunde willst, mußt Du optimieren. Im übrigen: Netzwerk fällt bei localhost auch nicht weg, das läuft den Stack hoch und runter. Nur mal so am Rande bemerkt.
Wie man Dir schon sagte … Der Flaschenhals ist vor allem die IO-Leistung deiner HW … moderne PC langweilen sind fast immer wenn sie mit Datenbanken operieren - AUCH wenn du auf local-host arbeitest … Da bringt es auch nichts wenn du Fantastilliarden GHz Prozessoren und fünfmal soviel RAM einbaust.
Wenn z.B. die Festplatte damit beschäftigt ist, die Köpfe neu zu positionieren und Sektoren zu suchen, hat der Prozessor Urlaub. Die CPU-Auslastung die du siehst ist kein Grund in Panik zu verfallen.
Ahso, dann dauert also doch das schreiben so lange. Im wesentlichen ist die Wartezeit dann also die Zeit in der die festplatte arbeitet/wartet. Nagut, damit kann ich mich abfinden.
Vielen Dank fürs Erklären!
Halt! Eine Frage noch:
Bei uns bekommen immer mehr Mitarbeiter nun ein Lenovo X300 mit SSD und da liegt ja der Gedanke nah, dass es auf dem viel besser laufen müsste. Lohnt es sich für mich das mal auszuprobieren?
Zum Thema SSD kann ads vielleicht noch was sagen, da bin ich mir aus bestimmten Gründen sicher… nur soviel: die haben eine schlechte Schreib-performance, Lesen geht flotter als als bei herkömmlichen Platten.
Richtig!
Beachte bitte auch das die Geschwindigkeit von Platten nicht Linear ist. Am Anfang der Platte schnell dann immer langsamer. Im schlimmsten Fall hat jemand sein OS auf einer Platte installiert ohne ende anderen Krams und dann in der Mitte oder am Ende der Platte PG dann juckelt das ganze mit 30 mb/sek durch die Gegend
Dieses Argument sollte man bei Betrachtung von Performance problemen die man hier liest nicht ausser acht lassen gerade wo PG so auf Sicherheit beim schreiben pocht (zum glück).
Beispiel:
SSD:
Wenn die dinger ausgereifter sind und man mehr Erfahrungen gesammelt hat sind sie prädestiniert für
den DB Einsatz (ich nutze seit ein paar Monaten selber eine). Was immer bemerkenswert bei SSD “Platten” ist das sie gleichzeitige Zugriffe besondert mögen und schnell sind.
Das müsste z.b. PG besonders gefallen wegen WAL log und co. schreiben.
Die Super Talent UltraDrive mit dem Indilinx Controller können nicht nur sau schnell lesen mittlerweile auch schnell schreiben.
Einen netten überblick gibt es hier:
hdtach_chart.jpg