Bulk Load
Verfasst: Di 13. Apr 2021, 04:50
Es geht um das Laden von großen Datenmengen in eine Firebird-DB, was alle betrifft, die Reporting und BI machen. Wir hatten das Thema bisher hier Firebird 4 bulk api und hier Firebird 3 UDR in Pascal/Delphi und hier Firebird Performance Newsletter: Ausgabe 1. Es ist nicht so, dass Firebird das nicht kann, die Möglichkeiten sind nur so unbekannt oder dürftig dokumentiert, dass die meisten sie nicht nutzen können.
Konkret gibt es für bulk load in Firebird die folgenden Möglichkeiten (Parallelisierung außen vor gelassen, weil es zuerst darauf ankommt, einen Ladevorgang mit brauchbarer Geschwindigkeit zu haben). Bei den Eingangsdaten können wir von csv ausgehen als kleinstem gemeinsamen Nenner:
Die Grundidee ist dabei, dass csv-Daten als BLOB vorliegen. csv-Daten haben bereits eine Struktur, die einer Folge von insert-Statements ziemlich ähnlich sind. Es sind durch Trenner getrennte Werte, wie sie im values-Part eines insert-Statements vorkommen. Eine Zeile csv bedeutet ein insert-Statement. Vor die Werte muss eine Aufzählung der Spaltennamen. Die Zieltabelle kann eine gleichförmige Tabelle aus n varchar-Spalten sein, zb 20 oder 50 Spalten mit jeweils varchar(100). Dh, man behandelt die Eingangsdaten beim Import unterschiedslos wie im Webbereich als Text, was den Import vereinfacht.
Das ganze innerhalb einer SP import_csv_blob. Diese SP transformiert die csv-Blobdaten in eine Folge von insert-statements, setzt die als den body eines execute blocks und führt den dann aus. Allerdings kann der body eines execute blocks in Firebird 3 maximal 32K lang sein, deswegen muss man die csv-Daten in passende Happen < 32K partitionieren, das ist die Schwierigkeit bei diesem Ansatz. Da der execute block nur einmal übersetzt wird, ist der Ansatz trotz der Happenbildung wesentlich schneller als alle anderen normalen Stapel-inserts, auch als inserts über prepared statements. Das ganze macht die SP dann in Happen kleiner 32K, bis der csv-Blob importiert ist. Das geht selbst mit Firebird 2.5.
UDR
Ab Firebird 3 gibt es UDR, user defined routines. Das sind extern definierte Routinen, die aber im Unterschied zu UDFs vollen Zugriff auf DB-Objekte und -Kontext haben und innerhalb von Transaktionen laufen. Fortsetzung folgt.
Konkret gibt es für bulk load in Firebird die folgenden Möglichkeiten (Parallelisierung außen vor gelassen, weil es zuerst darauf ankommt, einen Ladevorgang mit brauchbarer Geschwindigkeit zu haben). Bei den Eingangsdaten können wir von csv ausgehen als kleinstem gemeinsamen Nenner:
- execute block mit "insert script"
- UDR
Die Grundidee ist dabei, dass csv-Daten als BLOB vorliegen. csv-Daten haben bereits eine Struktur, die einer Folge von insert-Statements ziemlich ähnlich sind. Es sind durch Trenner getrennte Werte, wie sie im values-Part eines insert-Statements vorkommen. Eine Zeile csv bedeutet ein insert-Statement. Vor die Werte muss eine Aufzählung der Spaltennamen. Die Zieltabelle kann eine gleichförmige Tabelle aus n varchar-Spalten sein, zb 20 oder 50 Spalten mit jeweils varchar(100). Dh, man behandelt die Eingangsdaten beim Import unterschiedslos wie im Webbereich als Text, was den Import vereinfacht.
Das ganze innerhalb einer SP import_csv_blob. Diese SP transformiert die csv-Blobdaten in eine Folge von insert-statements, setzt die als den body eines execute blocks und führt den dann aus. Allerdings kann der body eines execute blocks in Firebird 3 maximal 32K lang sein, deswegen muss man die csv-Daten in passende Happen < 32K partitionieren, das ist die Schwierigkeit bei diesem Ansatz. Da der execute block nur einmal übersetzt wird, ist der Ansatz trotz der Happenbildung wesentlich schneller als alle anderen normalen Stapel-inserts, auch als inserts über prepared statements. Das ganze macht die SP dann in Happen kleiner 32K, bis der csv-Blob importiert ist. Das geht selbst mit Firebird 2.5.
UDR
Ab Firebird 3 gibt es UDR, user defined routines. Das sind extern definierte Routinen, die aber im Unterschied zu UDFs vollen Zugriff auf DB-Objekte und -Kontext haben und innerhalb von Transaktionen laufen. Fortsetzung folgt.