Teilzugriff auf BLOB Felder

Themen rund um den praktischen Einsatz von Firebird. Fragen zu SQL, Performance, Datenbankstrukturen, etc.

Moderator: thorben.braun

vr2
Beiträge: 214
Registriert: Fr 13. Apr 2018, 00:13

Hallo Ulrich,

bin gespannt, wie das ausgeht. Mir ist noch eingefallen:

Wenn Du die Daten eh auch in Dateien vorliegen hast, könntest Du fürs bulk load die gute alte external table nehmen. Das geht hier vermutlich einfach, weil Du a) Festformat hast, also definierte Feldlängen (alles bigint) und Feldanzahl (10 oder 100), und b) weil Du vermutlich keine <null>-Messpunkte hast. Dann wäre das Thema bulk load vom Tisch.

Falls das nicht geht, musst Du häufige Operationen auf Blobs vermeiden, das kann schnell der Flaschenhals werden. Und natürlich wenn möglich, den prepare-overhead bei insert statements vermeiden.

Oder Du bildest innerhalb einer SP einen Datenblock auf einen dynamisch erzeugten execute block ab, der insert-statements enthält und führst diesen execute block mit execute statement in der SP aus, im Prinzip ein blockweise dynamisch erzeugtes insert-skript. Das sql für den execute block darf aber nicht größer als 32K sein. Die Abbildung eines Datenblocks auf insert-statements sollte dabei nicht über Schleife, sondern wenn das geht, als ganzes passieren. Angenommen, Du hast Messdaten in der Art

1234 4711 2233 4321
1266 4712 2244 4442
1277 4713 2255 4311

also so eine Art csv-Format, dann ist das ganze schon relativ nahe an den entsprechenden insert-statements - den Datenblock mit einigen replace umgeformt musst Du nicht jeden Wert und jede Zeile einzeln anpacken. Das würde dann der body des execute blocks:

insert into zieltabelle values (1234, 4711, 2233, 4321);
insert into zieltabelle values (1266, 4712, 2244, 4442);
insert into zieltabelle values (1277, 4713, 2255, 4311);

Oder Du benutzt eine UDR fürs bulk load. Aber das ist wieder ein ganz anderes Fass, das man aufmachen kann ;-)

Viele Grüße, Volker
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Die schnellste Methode für Inserts ist tatsächlich, den Prepare zu sparen. Dies erreicht man in der Verwendung von Parametermarkern. Dies gilt i.Ü. für alle DB's und alle Nicht-DDL-Befehle.
Also "insert into mytable (?, ?, ?, ...., ?)". Dasselbe gilt eben auch für Update/Delete/Select. Der Overhead der Interpretation eines SQL's entfällt vollständig.
Die meisten Programmiersprachen unterstützen sog. Command-Objekte mit denen ich Parameter-Auflistungen verwenden kann.
Bei Tabellen mit wenigen Feldern erreiche da mehrere 1000 Inserts/Sekunde.
Ich verwende da auch mal gerne bis zu 4 Threads in parallelen Verbindungen.
In Summe sind das bis zu 15.000 Inserts / Sekunden.
Bei der FB 2.5 geht das nur im Classic-Modus, da jede Connection einen eigenen Prozess erhält und somit die gesamte CPU-Bandbreite genutzt werden kann.

Die Frage ist halt, in welcher Zeit die 100Mio Werte entstehen.
Bei angenommenen 15.000 Inserts/Sekunde sind das halt immer noch 1,8 Stunden.

Bei der angegebenen Informationslänge (Short+Float+Byte) = 7 Bytes sind das knapp 670 MB. Bei Dateiausgabe und einer Schreibleistung von 500MB bei einer SSD erklärt sich nun von selber, dass die Dateiausgabe da schon um Faktoren schneller geht.
Groffy
Beiträge: 78
Registriert: Do 12. Apr 2018, 23:14

Hallo Volker, bfuerchau

ich habe zwar noch ein wenig probiert, aber schneller als das dateibasierte Speichern der Messdaten geht wohl nicht. Das schreiben/lesen im FITS Format ist einfach sehr schnell (mehr als eine Größenordung schneller als mit Datenbank), und ich denke für die Anwendungen bei denen wir die Zeilensensoren einsetzen ist das der richtige Weg.

Vielen Dank für eure Unterstützung - beste Grüße Ulrich
Antworten