![]() |
Datenbank: MySQL • Version: 4.0.16 • Zugriff über: ADO
ADO Command mit mehreren Inserts
Hallo!
Habe folgende Aufgabe: Bestimmte Datenpunkte (bis zu 10000 Stück!) müssen über Monate bis Jahre hinaus in einer Datenbank archiviert werden. Die Zustandsänderung wird jede Sekunde archiviert. Für jeden Datenpunkt wird eine Tabelle angelegt: dp1 bis dp9999. Die Tabelle besitzt nur zwei Spalten (Timestamp und Wert). Natürlich muss ich bei der Anzahl von Tabellen unmöglich sein ADOCommando.Execute in einer Schlaufe laufen zu lassen (aus Spaß getestet ;) - bei 250 Executes pro Sekunde ist Schicht im Schacht) Die Insert-Anweisungen sollten deshalb gesammelt werden und in Paketen über ein ADOCommando.Execute gesendet werden. (wie in einer Dump-Datei). Und hier taucht schon ein Problem auf: Dies funktioniert problemlos:
Delphi-Quellcode:
Das Sammeln von Werten für einen Datenpunkt in einer Insert-Anweisung funktioniert ebenfalls:
commando := 'INSERT INTO dp1 VALUES (' + unixstamp + ', ' + wert + ');';
ADOCommando.CommandText := commando; ADOCommando.Execute;
Delphi-Quellcode:
Das funktioniert gar nicht:
commando := 'INSERT INTO dp1 VALUES (1137061871, 0.568),(1137061872, 0.654),(1137061873, 0.564)';
ADOCommando.CommandText := commando; ADOCommando.Execute;
Delphi-Quellcode:
Hat jemand eine Ahnung woran es liegen mag?!?
commando :=
'INSERT INTO dp1 VALUES (1137061871, 0.5); ' + 'INSERT INTO dp2 VALUES (1137061871, 0.5); ' + 'INSERT INTO dp3 VALUES (1137061871, 0.5); ' + 'INSERT INTO dp4 VALUES (1137061871, 0.5); ' + 'INSERT INTO dp5 VALUES (1137061871, 0.5); ' + 'INSERT INTO dp6 VALUES (1137061871, 0.5); ' + 'INSERT INTO dp7 VALUES (1137061871, 0.5); ' + 'INSERT INTO dp8 VALUES (1137061871, 0.5); ' + 'INSERT INTO dp9 VALUES (1137061871, 0.5); ' + 'INSERT INTO dp10 VALUES (1137061871, 0.5); '; ADOCommando.CommandText := commando; ADOCommando.Execute; Es schaut so aus, also ob man in einen CommandText des ADOCommand nur eine Tabelle ansprechen könnte, aber das ist doch Quatsch. Ich will doch reines SQL über die Schnittstelle schieben... Gebe ich dieselbe SQL-Anweisung an die Datenbank über ein Tool wie phpMyAdmin ein, werden die Inserts ausgeführt... Falls jemand es ausprobieren möchte hier der Code für die Tabellen erstellung (für 10 Datenpunkte):
Delphi-Quellcode:
Danke im Voraus für die Mühe!procedure TForm1.Button1Click(Sender: TObject); var i: Word; table: String; begin for i := 1 to 10 do begin table := 'dp' + IntToStr(i); ADOCommandDelete.CommandText := 'DROP TABLE IF EXISTS ' + table; eSQLBefehl.Text := ADOCommandDelete.CommandText; ADOCommandDelete.Execute; end; for i := 1 to 10 do begin table := 'dp' + IntToStr(i); ADOCommandDelete.CommandText := 'CREATE TABLE ' + table + ' ( ' + 'tstemp int(12) NOT NULL default 0, ' + 'dpvalue float(16,15) NOT NULL default 0.000000000000000, ' + 'PRIMARY KEY (tstemp) ' + ') TYPE=MyISAM;'; ADOCommandDelete.Execute; end; end; |
Re: ADO Command mit mehreren Inserts
Ich habe ein paar Anmerkungen:
1, Wieso nutzt du ADO? Für MySQL gibt es doch mit MyDAC eine sehr gute native Zugriffskomponente. Auch die ZEOS-Komponenten sind ganz gut für MySQL. 2, Hattest Du schon probiert mit Prepared Statements die Performance zu verbessern? 3, Falls Du MySQL 5.0 einsetzen könntest, könntest Du probieren mittels SP's die Performance nochmals zu verbessern. |
Re: ADO Command mit mehreren Inserts
IMHO ist dein Datenbankdesign recht... nunja... wie soll ich sagen... ungünstig :roll:
Warum legst du für jeden Punkt eine separate Tabelle an? Für deine Aufgabe reicht eine einzige Tabelle. Die lässt sich dann auch wesentlich leichter auswerten.
SQL-Code:
CREATE TABLE MESSPUNKTE(
ID INTEGER NOT NULL, DATENPUNKTID INTEGER, DATUMZEIT TIMESTAMP, WERT DOUBLE PRECISION) |
Re: ADO Command mit mehreren Inserts
Zitat:
2. Nein noch nicht 3. Ich nutze MySQL4 zum Test. Alles soll aber auf Standard-SQL laufen, also keine Spezial-Performance Funktionen... :( |
Re: ADO Command mit mehreren Inserts
Zitat:
Zitat:
|
Re: ADO Command mit mehreren Inserts
Zitat:
Hast Recht, aber ich muss mich an Vorgaben halten :( Es ist eine Umstetzung eines bereits vorhandenen Tools, welches für jeden Datenpunkt eine Textdatei erzeugt. Die Dateien (hier einzelne Tabellen) müssen separat gesichert werden können. Das zweite Problem ist: Es entstehen pro Datenpunkt 31.536.000 Datensätze pro Jahr (und das ist die Mindestzeit der Archivierung). Damit ist jede Tabelle ca. 0,5 GB groß und läßt sich einzeln ganz gut wegsichern. Würde ich alle 10.000 Datenpunkte in eine Tabelle packen und über die DatenpunktID ansprechen, hätte ich im Januar 2007 eine Tabelle mit 315.360.000.000 Datensätzen und > 5.000 GB. Das können wir gleich vergessen... Das alles könnte man ja noch lösen, aber das blödeste sind die Vorgaben... Und ich stehe schon am Anfang vor einem Problem, welches so einfach erscheint... Trotzdem danke! |
Re: ADO Command mit mehreren Inserts
Zitat:
SQL-Code:
die sind nämlich MySQL spezifisch.
INSERT INTO dp1 VALUES (1137061871, 0.568),(1137061872, 0.654),(1137061873, 0.564)
Mal so ne Frage... Was sind das für Daten, dass nach 1 Jahr über 300 Milliarden Datensätze anfallen... Die kannst Du doch unmöglich noch auswerten. |
Re: ADO Command mit mehreren Inserts
Zitat:
Zitat:
Außerdem bist du mit der Eintabellenlösung flexibler auf die Änderung der Messpunktanzahl vorbereitet. Zitat:
|
Re: ADO Command mit mehreren Inserts
Bei der Anzahl der Datensätze und "einfachheit" eines Datensatzes ist es eh fraglich ob man das Sinnvoll überhaupt jeden Wert als einzelnen Tabelleneintrag eintragen sollte? Evtl. ist eine Speicherung als Blob für größere Zeiträume sinnvoller oder direkt die Meßdaten extern speichern. Es ist nämlich Fraglich ob du noch performant bei mehreren Mio./Mrd. Datensätzen Einträge vornehmen kannst bzw. in endlicher Zeit Reports fahren kannst und zwar ganz unabhängig ob es MySQL oder auch ein MS-SQL oder Oracle wäre.
Ich würde erstmal die Datenbank über mehrere Tage mit Testdaten füllen um zu sehen wie sie überhaupt mit diesem Ansatz reagiert. Die angedachte Trennung ist m.E. bei der Datenmenge sinnvoll (Hab ich schon mal in ähnlicher Form aber bei komplexeren Records auch gemacht). Denn es ist fraglich ob eine Tabelle mit 31 Mio * 10.000 Datensätzen auch mit passenden Indexen auf "normalen" PC's noch vernünftig abfragbar ist. Indexe müssen um schnell zu sein möglichst komplett im Hauptspeicher liegen. Und ob du da mit ein paar GB Hauptspeicher bei voller Datenbank auskommmst? :gruebel: |
Re: ADO Command mit mehreren Inserts
Ich würde Bernhard Aussage unterstützen ...
Bei dieser Anzahl von Datensätzen helfen Dir auch die Möglichkeiten zur Segmentierung der Daten (Aufteilung z.B. in zwei Tabellen mit neuen bzw. alten Daten) nicht weiter um Abfragen in vernünftiger Zeit durchführen zu können. Nimm z.B. ein BLOB-Feld in dem Du den Inhalt einer Textdatei mit allen Messdaten je Tag (oder Stunde?) speicherst. Die Datenbank enthält denn je Zeitintervall einen Datensatz mit dem Inhalt der Datei und ggf. zusammenfassenden Daten die sich aus den Messdaten ergeben und deine Abfragen sind sehr schnell ... Falls Du wirklich die einzelnen Daten eines Zeitintervalls brauchst, mußt Du eben den gespeicherten Text "auseinandernehmen". Viel Erfolg. Niels P.S. Die "Vorgaben", die vom Auftraggeber sollte selbst dann hinterfragen wenn dieser EDV-Experte ist. In den meisten Fällen steht hinter der Vorgabe "Jeder Messpunkt soll gespeichert werden" lediglich eine gewünschte Funktionalität. Diese kann man auf unterschiedlichsten Wegen gewährleisten ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz