Einzelnen Beitrag anzeigen

Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
672 Beiträge
 
FreePascal / Lazarus
 
#66

AW: Fragen bezüglich Performance von Firebird in einer Anwendung

  Alt 15. Aug 2019, 17:02
INSERT INTO Tabelle (Feld1, Feld2) VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5,5); Macht in Summe genau 80 Zeichen. Bei Firebird habe ich stattdessen Execute-Blocks, womit für das selbe Ergebnis folgendes zu notieren wäre:
SQL-Code:
EXECUTE BLOCK AS BEGIN
INSERT INTO Tabelle (Feld1, Feld2) VALUES (1, 1);
INSERT INTO Tabelle (Feld1, Feld2) VALUES (2, 2);
INSERT INTO Tabelle (Feld1, Feld2) VALUES (3, 3);
INSERT INTO Tabelle (Feld1, Feld2) VALUES (4, 4);
INSERT INTO Tabelle (Feld1, Feld2) VALUES (5, 5);
END
Konstruktiver Vorschlag aus der Praxis, wie wir das gar nicht mal selten machen (unter anderen täglich mit ca 15mb CSV Wetter Daten aus den weltweiten WMO Synop und Forecast Daten)

Der Inhalt wird per Upload in eine Tabelle mit einem Blob Feld inserted und dann per Execute Procedure mit Hilfe diverse Substring, Position, oder eigener Stored Functions serverseitig auseinander genommen , in Execute Statements übersetzt und von da in die realen Tabellen verteilt. Die Rohdaten sind dabei ca 150.000 zeilen und das geht auf dem Weg wesentlich schneller als man denkt, insbesondere weit schneller als 150.000 Einzelinserts.

Ein anderer Weg: Du baust deine Execute Blocks lokal wie vermutlich auch schon jetzt in deiner Clientumgebung zusammen und berücksichtigst einfach nur die Limits, die Firebird da hat (maximal 32k source pro Block, maximal ca. 250 inserts oder max ca. 125 updates oder max ca. 83 update or inserts, etc. Die Blöcke kannst du dann mit einem Trenner deiner Wahl zum Beispiel auch in einen Blob auf den Server hochladen oder dort mit einer ähnlichen SP (siehe oben) dann serverseitig mit einzelnen execute statement der aufgeteilten execute blocks ausführen. Läuft alles in einem Transaktionskontext und rollback ist rollback etc.

Wir haben in Ibexpert scripten eine Möglichkeit eingebaut, einen Reinsert zu integrieren, was ein simpler Ersatz für das vorher benutzte voll ausformuliert Insert ist. Das macht Scripte schon wesentlich kleiner.

Und in einer für unserer Zwecke erweiterte Firebird Version auf Basis der 304 ist ein Vorabparser eingebaut, der Sqls serverseitig auseinandernehmen kann, bevor die firebird internen Instanzen den SQL Text überhaupt sehen.

Mit dem ist auch deine Multirow insert syntax möglich, aber aus welchen gründen auch immer ist das aktuell nicht in der Public Firebird Version implementiert, obwohl die eben als Datenpumpe durchaus für kleinere Scripte sorgen kann. Technisch ist aber der weg upload als blob und execute auf dem Server nicht so viel anders und auch nicht wirklich langsamer, weil egal wie der text lautet, in dem man die Operationen zum Server sendet, am ende physikalisch inserts auf der db gemacht werden.

Und auch da am Ende meine Zustimmung: Die von dir erwähnte Syntax für Massenimporte bietet viel potential und ist bei der Implementation für die Firebird Entwickler sicherlich keine Raketenwissenschaft, aber da es durchaus gleichschnelle Workarounds gibt, scheinbar auch nicht ganz so wichtig, aber es steht dir offen, das bei Bedarf im Bugtracker vom Firebird Projekt als Feature einzutragen oder falls schon vorhanden, deine Interesse zu bekunden, das du es für Wichtig hältst.

Wenn es aber darum geht, möglichst schnell daten in die Datenbank zu bekommen, oder auch Daten aus der Datenbank zu exportieren, dann nimm besser ein Verfahren über external file tables, damit geht das auf schnellen Servern problemlos 50000-100000 import/export records pro Sekunde!!
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung

Geändert von IBExpert (15. Aug 2019 um 17:05 Uhr)
  Mit Zitat antworten Zitat