Schnelle Befüllung von MS-SQL-Tabellen?

27/04/2011 - 02:06 von Thomas G. Liesner | Report spam
Guten Tag!

Ich arbeite in jüngerer Zeit hàufiger an Konvertierungen, deren
Ergebnisse jeweils in eine MS-SQL-Server-Datenbank kommen. Bei dem
jüngsten Projekt ist mir aufgrund der Datengröße die Asymetrie zwischen
Laden und Speichern besonders aufgefallen - das Laden der 500.000
Datensàtze aus Paradox-Tabellen und Füllen in ein komplexeres internes
Modell dauert nur ein paar Minuten, das Schreiben in die Zieldatenbank
dagegen ca. 50 Minuten.

Momentan verwende ich intern ein TAdoDataset mit CommandText "Select *
from Tabellenname" und Append/FieldbyName(...)/Post zum Schreiben der
Datensàtze. Bei kleinen Datenmengen ist das flott, bei größeren geht der
Speicherverbrauch temporàr ganz gut hoch und es scheint gegen Ende immer
langsamer zu füllen. CommitTrans machte ich vorher nach jeder gefüllten
Tabelle, ein Umstellen auf pro Datensatz ànderte das Zeitverhalten nicht
erkennbar.

Welche schnelleren Alternativen gibt es? Drauflos experimentieren will
ich deshalb nicht, weil der entsprechende Umbau relativ aufwendig wàre
und ich zumindest wissen möchte, ob sich der Aufwand lohnt.

Eine (recht aufwendig zu implementierende) Alternative wàre auf jeden
Fall wohl das Schreiben mit einem Insert-Statement pro Datensatz, würde
das erkennbar was bringen oder sogar langsamer sein können?

Ein wesentliches Kriterium der Alternativlösung muss dabei sein, dass
ich die ID eines neuen Datensatzes direkt erfahren kann, wie bislang
durch simples Einlesen des ID-Feldes nach dem POST...

So long,
Thomas G. Liesner
 

Lesen sie die antworten

#1 Joe Galinke
27/04/2011 - 08:36 | Warnen spam
Hallo Thomas,

Thomas G. Liesner schrieb:

[... zu langsames Schreiben großer Datenmengen in MySQL ...]

Eine wirkliche Lösung kann ich leider nicht anbieten, aber vielleicht
Anstöße.

Der erste ist die Verwendung von Bulk-Inserts, also einem INSERT-Statement
mit vielen Datensàtzen, mehreren VALUES-Listen.

Leider kollidiert das mit Deinem Kriterium bzgl. der Kenntnis über die ID
des Datensatzes.

Ein wesentliches Kriterium der Alternativlösung muss dabei sein, dass
ich die ID eines neuen Datensatzes direkt erfahren kann, wie bislang
durch simples Einlesen des ID-Feldes nach dem POST...




Demnach verwendest Du AUTO_INCREMENT, MySQL kennt keine Generatoren für
Sequenzen?

Handelt es sich um eine überschaubare Anzahl von Zieltabellen _und_ ist das
Einfügen von Datensàtzen von anderen Prozessen wàhrend Deines
Einlesevorgangs ausgeschlossen?

Wenn ja, könnte zu Beginn die aktuell höchste ID mit LAST_INSERT_ID
ausgelesen werden und von dort an wird der Wert selbst verwaltet.
Zumindest die InnoDB-Engine soll es unterstützen, dass man den Wert des
Feldes selbst festlegt. So dieser 0 oder NULL ist, wird er von der Engine
nicht mit einem neuen Wert versehen.

Welche MySQL-Version kommt überhaupt zum Einsatz? Wurde InnoDB nicht
irgendwann sogar zur Standardengine?

Auf jeden Fall sollte es sich einfach testen lassen, wie das System mit
programmseitig gesetzten AUTO_INCREMENT-Spalten umgeht und ob bei spàteren
"normalen" INSERTs wirklich der nàchste neue Wert auf dem aktuellen und
nicht auf dem alten ID-Wert basiert.

Gruß, Joe

Ähnliche fragen