Performancevergleich Firebird 2.5 vs 3 oder 4 bei prepared inserts

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

Moderator: thorben.braun

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

Hallo alle,

beim Durchgehen der Neuerungen / Bugfixe von Firebird 3.0.8 fiel mir dieses ältere Ticket auf: https://github.com/FirebirdSQL/firebird/issues/5877. Es geht dabei um den erhöhten Speicherbedarf, den prepared statements bei Firebird 3 oder 4 im Vergleich zu Firebird 2.5 anscheinend haben. Der Bugfix, in Firebird 4 schon länger umgesetzt, wurde jetzt zu Firebird 3.0.8 zurückportiert, was aber in beiden Versionen nicht bedeutet, dass die nennenswerten Unterschiede beim Speicherbedarf im Vergleich zu Firebird 2.5 damit vollständig beseitigt sind, sondern nur etwas verringert. Firebird 3 und 4 verwalten mehr Kontext in den Strukturen für die Statements als Firebird 2.5, von daher lässt sich das wohl nicht komplett wegoptimieren.

Konkret fiel mir das in einer Testanwendung auf, die bulk inserts in eine DB macht, über ODBC werden irgendwelche Quellen mit Millionen von Datensätzen gelesen und nach Firebird importiert. Dabei werden jeweils 100K Sätze gelesen, übergeben und jeweils nach 100K Sätzen findet ein commit statt. Das commit ist nicht der Punkt, aber die "Rundenzeit", also die Zeit für die Übergabe der 100K Statements an den Server braucht bei Firebird 4 zumindest bei meinen Tests reproduzierbar etwas länger als bei 2.5. Größenordnung bspw 6 statt 5 Sekunden auf einem bestimmten Rechner, also schon signifikant. Hat man bspw 1,5 Mio Sätze zu importieren, sind das 15 sek mehr, insgesamt dann 90 statt 75 sek, immerhin 20% mehr.

Diese Zeitabweichung scheint auch abzuhängen von der Hardware und ist auf verschiedenen Rechnern (mit oder ohne Virtualisierung) unterschiedlich hoch, aber vorhanden. Irgendwie plausibel, wenn man von einem erhöhten Speicherbedarf bei Firebird 3 oder 4 ausgeht. In meinem Testszenario waren alle Komponenten gleich, also die selbe Anwendung, die selben Datenquellen, die selbe fbclient (2.5.9), ZielDB gleich konfiguriert, zb bei DefaultDbCachePages, keine Indizes auf der Zieltabelle, nur am anderen Ende entweder Firebird 2.5 oder Firebird 4 (der für legacy Zugriff über die 2.5.9er fbclient konfiguriert ist). Für Firebird 3 müsste das genauso zutreffen.

Falls ihr Anwendungen habt, die Masseninserts via prepared statements machen, könnt ihr die Beobachtung bestätigen, dass Firebird 3 oder 4 gegenüber 2.5 mehr Zeit dafür braucht? Es muss mindestens in der Größenordnung mehrere 100K Sätze sein, sonst ist der Effekt nicht wahrnehmbar.

Viele Grüße, Volker
jhoehne
Beiträge: 22
Registriert: Di 11. Dez 2018, 09:19

In Firebird 4 gibts ja jetzt das Batch Api, genau für solche Fälle. Ich könnte mir vorstellen, dass das über ODBC gar nicht geht, weil es eine API Funktion ist und kein spezieller SQL-Befehl. Die Bibliothek "MWA-IBX2" in der neusten Version 2.4.3 für Lazarus kann das aber. Ich hab nur keine Zeit fürs Testen...
--
Joachim
vr2
Beiträge: 120
Registriert: Fr 13. Apr 2018, 00:13

Vielen Dank für den Hinweis, fbintf ist anscheinend die erste lib für pascalartige Sprachen, die das neue Firebird-API unterstützt, Infos für die Nutzung des Batch-APIs waren bisher kaum zu bekommen, geschweige denn libs, die das können. Teste ...

ODBC hatte ich nur als Quelle im Test, das ist egal, hätte auch csv aus Datei oder Stream sein können, es ging um Performance beim Schreiben in die Tabelle, also die Zielseite.

Grüße, Volker
vr2
Beiträge: 120
Registriert: Fr 13. Apr 2018, 00:13

Hier standen noch die Testergebnisse aus.

Habe fbintf (https://mwasoftware.co.uk/fb-pascal-api) getestet, das ist der standalone nutzbare Firebird-API-Teil von IBX, mehr brauchte ich nicht. fbintf steht für Firebird Interface. Das sieht gut aus, gut geschriebener Code, gute Doku. Tatsächlich die erste vollständige Pascal-lib fürs Firebird 4-API. Hier die Ergebnisse, verschiedene Windows-Rechner/Server, Firebird 4 64 Bit, > 1Mio Testdatensätze, Testanwendungen mit Delphi 10.4 übersetzt:

- Das batch API ist bei inserts ca 2 bis 4 mal so schnell wie die herkömmliche prepared-insert-Methode
- Als default row limit habe ich 16K verwendet. Der batch buffer kann max 256MB groß sein und ergibt sich bisher aus dem row limit * alignedLength einer Satz-Message
- Beim Erreichen des row limits werden die bis dahin angesammelten batch-Sätze übertragen
- höheres row limit bringt keine Performanceverbesserung, ist evtl abh von Plattenschreibgeschwindigkeit.
- fbintf erlaubt es, explizit andere fbclient-libs anzugeben, so kann eine Anwendung zwei verschiedene nutzen, wenn nötig
- fbintf muss nicht für eine bestimmte Firebird-Version übersetzt werden, es kann die maximal nutzbare Version selbst ermitteln
- wire compression brachte es zumindest lokal nicht, war sogar etwas schlechter

Nochmal vielen Dank für den Tip an jhoehne.

Grüße, Volker
Antworten