![]() |
Datenbank: Firebird • Version: 2.5.2.26540 • Zugriff über: iSQL
Wie bekomme ich einen performanten Firebird?
Ich habe zum Test auf einem unserer Server Firebird als SuperClassic installiert. Um die Performance zu testen wollte ich aus einer anderen Datenbank Testdaten übertragen und dann einge Quälscripts laufen lassen.
Leider bin ich jetzt der Gequälte. Nach der Anlage der Datenbank und Tabellen füge ich Testdaten per iSQL-Script hinzu. Die Laufzeit ist aber ziemlich unterirdisch. Für 100 Records werden ca. 3-5 Sekunden benötigt. Das ist meherere hundert Male langsamer als ich das von anderen DB-Servern kenne. Was kann ich wo und wie drehen, damit die Performance besser wird? Systemauslastung ist bei unter 1%. System: Windows 2008 Server R2 2x Intel Xeon E6520 (zus. 16 Kerne) 24 GB Speicher |
AW: Wie bekomme ich einen performanten Firebird?
-Alle Inserts innerhalb einer Transaktion? Wie sieht das Skript aus (Insert, Insert or Update, Merge?)
-Werden mehrere Kerne verwendet? ( Parameter -m, AffinityMask) -Aktive Trigger? |
AW: Wie bekomme ich einen performanten Firebird?
Ich mach das immer so:
|
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
|
AW: Wie bekomme ich einen performanten Firebird?
Das Script sieht so aus (mit 50000 inserts):
Code:
Die Installation habe ich mit der Batchdatei aus dem Zipkit gemacht, ohne irgendwas zu ändern.
Insert into Bestand values(21654631, 23, '1918298', 23899, null, null, null, '20', '2020682276', 21649245, 747, 21649993, null, null, 'IT', '/', 'IT', 40.34, 'Ft', null, null, 147390, 2573092, null, null, null, '2008-06-12', '11:12:05', '2009-03-25', null, 6, 0, null, null);
Insert into Bestand values(22138465, 24, '2543234', 19510874, null, null, null, '0001', '7022371544', 22110364, 220, 22110386, null, null, 'CN', null, null, 0, null, null, null, 147390, 144627, null, null, null, '2009-03-25', '15:17:32', null, null, 2, 0.03696, null, null); Insert into Bestand values(22156974, 23, '2577937', 64322, null, null, null, '20', '2020682334', 22128344, 399, 22128744, null, null, 'ES', '/', 'ES', 8.86, 'Ft', null, null, 69667, 105578, null, null, null, '2009-04-14', '15:59:51', null, null, 4, 0, null, null); -- ... Alle 100 records ein commit: commit; @perlsau: das insert script habe ich mit einem selbsterstellten tool aus einer Produktions-DB eines anderen DB-Servers generiert. |
AW: Wie bekomme ich einen performanten Firebird?
Gibt es aktive Trigger/Constraints?
Massenimport als externe Tabelle ist die schnellste Alternative |
AW: Wie bekomme ich einen performanten Firebird?
Keine Trigger, keine Constraints, keine Relationen. Aber 8 Indizes:
Code:
CREATE INDEX "BESTAND_ID" ON BESTAND (ID);
CREATE INDEX "BESTAND_MAND_ID" ON BESTAND (MAND_ID, ART_ID); CREATE INDEX "BESTAND_ART_ID" ON BESTAND (ART_ID, MAND_ID); CREATE INDEX "BESTAND_ZUG_NR" ON BESTAND (ZUG_NR, MAND_ID, ART_ID); CREATE INDEX "BESTAND_PAL_NR" ON BESTAND (MAND_ID, PAL_NR); CREATE INDEX "BESTAND_FIFO" ON BESTAND (MAND_ID, ART_ID, ZUG_DAT, ZUG_ZEIT); CREATE INDEX "BESTAND_PLATZ_ID" ON BESTAND (PLATZ_ID, ART_ID, ZUG_DAT); CREATE INDEX "BESTAND_KUND_ID" ON BESTAND (KUNDE_ID); |
AW: Wie bekomme ich einen performanten Firebird?
Schalte mal alle nicht absolut benötigten (alles ausser Primary Indices) aus. Massenimport und viele Indices ist ganz schlecht - bei jedem DBMS.
Edit: Nach beendetem Import dann alle vorher deaktivierten Indices neu aufbauen lassen. |
AW: Wie bekomme ich einen performanten Firebird?
Diese würde ich temporär deaktivieren
SQL-Code:
und am Ende neu berechnen lassen.
alter index <Indexname> inactive;
SQL-Code:
SET statistics INDEX <Indexname>;
|
AW: Wie bekomme ich einen performanten Firebird?
Klar dass ein Indexupdate Zeit braucht. Aber ein Durchsatz von nur 5 Records/s ist doch etwas fragwürdig. In der Zeit schreibe ich normalerweise ein komplette SAP-SHPORD mit mehreren 100 records. Und Massenupdates sind auch in der Produktion an der Tagesordnung, wenn Material Master Updates laufen. Da liegt die Geschwindigkeit bei > 1000 IDoc / min. inklusive Analyse.
|
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
Ist richtig, um es aber explizit darzustellen: nach
SQL-Code:
und Import zunächst
alter index <Indexname> inactive;
SQL-Code:
und erst dann
alter index <Indexname> active;
SQL-Code:
SET statistics INDEX <Indexname>;
|
AW: Wie bekomme ich einen performanten Firebird?
Stimmt. Davon bin ich implizit ausgegangen ohne es explizit zu schreiben.
|
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
Ich würde zusätzlich zu den anderen Tipps auch danach schauen, ob man in deinem Tool einstellen kann, wie häufig ein Commit ausgeführt wird. Keine Ahnung, wieviele Datensätze Firebird ohne Commit speichern kann, aber ich denke, es sind mehr als 1000. |
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
Wie führst Du das Skript aus? Eventuell funkrt Dir da doch noch ein AutoCommit dazwischen. |
AW: Wie bekomme ich einen performanten Firebird?
Es scheint an den "mehrfelder" Indizes zu liegen. Ich habe jetzt (nach 2:45h für 50000 Records) den Import für die nächste Test-Tabelle gestartet. Für diese sind nur einfache Indizes definiert. Dort hat er den Import von 110000 Sätzen nach 6 min. Auch noch nicht berauschend, aber es geht.
Die scripts führe ich mit
Code:
in der iSQL-Kommandozeile aus.
input
gstat sagt folgendes: Database header page information: Zitat:
|
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
Wenn ich wüßte, wie man via Server Manager ein Insert-Script einer MSSQL-Tabelle generiert, würde ich mal testweise meine riesige 900000 DS große Ortsdatenbank exportieren und in Firebird einlesen, um zu sehen, wie lange das dauert. |
AW: Wie bekomme ich einen performanten Firebird?
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
|
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
Code:
Hab nur gerade keine Lust, ein Programm zu schreiben, das mir das Insert-Script generiert, ich schau mir nämlich nebenher einen Film an und gehe danach zu Bett, weil ich eigentlich schon saumäßig müde bin. Für das Anlegen einer Tabelle in FB würd's aber grad noch reichen :)
USE [GeoNames]
GO INSERT INTO [dbo].[Plaetze] ([ISO_Code] ,[Postal_Code] ,[Place_Name] ,[State] ,[State_Code] ,[Provinz] ,[Provinz_Code] ,[Kommune] ,[Kommune_Code] ,[Latitude] ,[Longitude] ,[Genau]) VALUES (<ISO_Code, char(2),> ,<Postal_Code, nvarchar(50),> ,<Place_Name, nvarchar(180),> ,<State, nvarchar(100),> ,<State_Code, nvarchar(50),> ,<Provinz, nvarchar(100),> ,<Provinz_Code, nvarchar(50),> ,<Kommune, nvarchar(100),> ,<Kommune_Code, nvarchar(50),> ,<Latitude, numeric(7,4),> ,<Longitude, numeric(7,4),> ,<Genau, tinyint,>) GO |
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
|
AW: Wie bekomme ich einen performanten Firebird?
Genau das hatte ich befürchtet: Da hat man nun ein gewaltig aufgeblähtes Werkzeug und kann nicht mal Insert-Scripts erzeugen. Okay, vielleicht mach ich das morgen mal mit einer Stringliste. Bis dann ...
|
AW: Wie bekomme ich einen performanten Firebird?
Liste der Anhänge anzeigen (Anzahl: 1)
Es geht doch. Dazu im Kontextmenü der Datenbank Tasks->Scripts generieren auswählen und im "Erweitert" Dialog auch auswählen, dass man Daten exportieren möchte. Nur wass Du mit TSQL in FB anfangen willst.... Lieber die Variante mit der Stringlist (wenn die bei 1 Mio nicht überläuft).
Hier mal als Vorlage mein primitivst-QD:
Delphi-Quellcode:
procedure TForm1.ExtractData(ATableName: string);
function QuoteValue(AValue : string) : string; begin if pos(#33, AValue) > 0 then result := StringReplace(AValue, #33, #33#33, [rfReplaceAll]) else result := AValue; end; function BoolStr(AField : TField) : string; begin if AField.AsBoolean then result := 'T' else result := 'F'; end; var i : integer; LCount : integer; LRecords : integer; LLine : string; LValue : string; sl : TStringList; begin AdsQuery1.SQL.Text := 'Select * from '+ATableName; sl := TStringList.Create; try AdsQuery1.Active := True; LRecords := AdsQuery1.RecordCount; ProgressBar1.Position := 0; ProgressBar1.Step := 1; ProgressBar1.Max := LRecords; sl.Capacity := LRecords; DecimalSeparator := '.'; LCount := AdsQuery1.FieldCount; while not AdsQuery1.Eof do begin LLine := 'Insert into '+ATableName+' values('; for i := 0 to LCount-1 do begin if AdsQuery1.Fields[i].IsNull then LLine := LLine + 'null' else begin case AdsQuery1.Fields[i].DataType of ftDate : LLine := LLine + QuotedStr(FormatDateTime('yyyy-mm-dd', AdsQuery1.Fields[i].AsDateTime)); ftDateTime : LLine := LLine + QuotedStr(FormatDateTime('yyyy-mm-dd hh:nn:ss', AdsQuery1.Fields[i].AsDateTime)); ftTimeStamp : LLine := LLine + QuotedStr(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', AdsQuery1.Fields[i].AsDateTime)); ftBoolean : LLine := LLine + QuotedStr(BoolStr(AdsQuery1.Fields[i])); ftString : begin LValue := QuoteValue(AdsQuery1.Fields[i].AsString); LLine := LLine + QuotedStr(LValue); end; else LLine := LLine + AdsQuery1.Fields[i].AsString; end; end; LLine := LLine + ', '; end; LLine := copy(LLine, 1, length(LLine)-2) + ');'; sl.Add(LLine); AdsQuery1.Next; if (sl.Count mod 101 = 0) or AdsQuery1.Eof then sl.add('commit;'); ProgressBar1.StepIt; end; sl.SaveToFile(ATableName+'.sql'); finally sl.Free; AdsQuery1.Active := False; end; end; |
AW: Wie bekomme ich einen performanten Firebird?
Oh. Nett. Danke.
|
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
Tatsächlich hatte ich jedoch auch eine FB-Version dieser Tabelle (als View), deren Daten ich exportieren konnte. Dabei wurden 923168 Datensätze mit dieser Struktur exportiert:
Code:
Nun hab ich mir in FB eine ebensolche Tabelle in einer Testdatenbank angelegt, wobei P_IDX auf AutoInc steht und daher automatisch erzeugt wird. Selbstverständlich hab ich zuvor im Export P_IDX nicht ausgewählt. Der Import via Script-Editor (von Datei ausführen) dauerte knapp 7 Minuten (6:55), das war eine knapp 206 MB große SQL-Datei. Berechnungen, wie lange ein DS benötigte, könnt ihr sicher selbst anstellen.
P_IDX BIGINT NOT NULL,
P_LAND VARCHAR(100), P_PLZ VARCHAR(50), P_ORT VARCHAR(180), P_STATE VARCHAR(100), P_PROVINZ VARCHAR(100), P_KOMMUNE VARCHAR(100), P_LAT NUMERIC(7,4), P_LON NUMERIC(7,4), P_GENAU SMALLINT |
AW: Wie bekomme ich einen performanten Firebird?
Interessant wäre es jetzt, wie lange ein Import der selben Daten als EXTERNAL TABLE dauern würde:
Anlage externe Tabelle
SQL-Code:
Testexport in externe Datei:
CREATE TABLE _IMPORT EXTERNAL FILE '<Pfad zur externen Datei>' (
P_IDX BIGINT NOT NULL, P_LAND CHAR(100), P_PLZ CHAR(50), P_ORT CHAR(180), P_STATE CHAR(100), P_PROVINZ CHAR(100), P_KOMMUNE CHAR(100), P_LAT NUMERIC(7,4), P_LON NUMERIC(7,4), P_GENAU SMALLINT, CRLF CHAR(2) ); COMMIT;
SQL-Code:
Import:
INSERT INTO _IMPORT
SELECT <Felder vorhande Tabelle>, ascii_char(13) || ascii_char(10) FROM <vorhandene Tabelle>;
SQL-Code:
INSERT INTO <geleerte Tabelle/neue Tabelle im identischer Struktur>
SELECT <Felder ohne CRLF> from _IMPORT; |
AW: Wie bekomme ich einen performanten Firebird?
So, nachdem ich die Daten importiert bekam, habe ich einen Test gemacht. Die Lesegeschwindigkeit ist wirklich gut. Aber das Schreiben. Ich habe es jetzt mal mit IBExpert probiert. Da ist die Geschwindigkeit genauso schlecht bei Insert.
Bei jedem Commit hängt er eine ganze Weile - es ändert auch nichts wenn ich das ganze ohne Indizes mache. Das eigentliche Senden der Datensätze an den Server geht rasend schnell. Was muß ich denn nun wo drehen damit das besser wird? @perlsau: Danke für Deinen Test. Wie ist denn Deine Konfiguration? edit: Ich habe das Performanceproblem nun gelöst indem ich
Code:
auf die Datenbank losgelassen habe. Daraufhin wurden die 50000 Testdatensätze in 50 Sekunden geschrieben.
gfix -write async
Wie stelle ich das beim Erzeugen der Datenbank ein oder als Standard im Dienst? Und in der Doku wird davor gewarnt, dass es sein kann dass die Daten dann nie geschrieben werden und es Verluste bei einem Serverabstirz geben kann. |
AW: Wie bekomme ich einen performanten Firebird?
Hab gleich einen Arzttermin und daher keine Zeit mehr. DB und SQL-Datei kann man sich dort
![]() |
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
|
AW: Wie bekomme ich einen performanten Firebird?
Das mit dem async ist leider auch keine allgemeingültige Lösung. Wahrscheinlich fehlen irgendwelche Buffer. Ich importiere nun gerade eine Tabelle mit > 8 Mio. records und ab ca. 300000 wird es wieder ekelhaft langsam beim Commit.
|
AW: Wie bekomme ich einen performanten Firebird?
Welche Art von Commit machst du?
|
AW: Wie bekomme ich einen performanten Firebird?
Verwendest du auch die üblichen Praktiken wie Prepared Statements etc.?
|
AW: Wie bekomme ich einen performanten Firebird?
Nichts von alledem. Ich führe nur ein Script aus, das aus 8 Mio einzelnen Inserts besteht und nach jeweils 100 Inserts ein commit. Leider wird von FB ja (soweit ich weiss) die Syntax von meheren Value-Gruppen nicht untertstützt (Values (Values-1) [, (Values-n)]).
Es sind auch nicht sonderlich große Datensätze:
Code:
Momentan habe ich über gfix async und buffers 8000 eingestellt. Damit komme ich auf ca. 1 Mio records / h = ~ 300/s. Und je mehr es werden, desto länger dauert das commit, wobei dier Performance ab ca. 300000-500000 Sätzen schlagartig in den Keller geht. Die Übertragung der Daten ist aber schnell.
Insert into buchung values(147393, null, null, 23, 14299, '1', '35842011', 0, null, null, null, 0, null, '2005-05-02', null, 21, 145646, '2005-05-02', '17:46:55', 'ZUG', null, null, 'BWirth', null);
Insert into buchung values(147396, null, null, 23, 14302, '2', '35842011', 1, null, null, null, 0, null, '2005-05-02', null, 21, 145647, '2005-05-02', '18:03:21', 'ZUG', null, null, 'BWirth', null); Insert into buchung values(147399, null, null, 23, 14302, '3', '35842011', 1, null, null, null, 0, null, '2005-05-02', null, 21, 145648, '2005-05-02', '18:03:42', 'ZUG', null, null, 'BWirth', null); |
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
Server Version: WI-V2.5.2.26540 Firebird 2.5 Server Implementation: Firebird/x86-64/Windows NT Service Version: 2 Lade dir das ![]() |
AW: Wie bekomme ich einen performanten Firebird?
Es ist auch nicht jedes 100er commit so langsam, nur ca. alle 4000 records.
|
AW: Wie bekomme ich einen performanten Firebird?
Ohne einem parametrisierten INSERT oder über den bereits erwähnten Weg via EXTERNAL TABLE wirst du für Batch-Inserts nie eine akzeptable Performanz erreichen.
Nochmal zu meiner Frage: Welche Art von Commit verwendest du? :-D |
AW: Wie bekomme ich einen performanten Firebird?
K.A. ich habe ei fach in jeder 100. Zeile des scripts ein
Code:
commit;
|
AW: Wie bekomme ich einen performanten Firebird?
Zitat:
Beispiel-Insert-Zeile:
Code:
INSERT INTO V_PLAETZE (P_LAND, P_PLZ, P_ORT, P_STATE, P_PROVINZ, P_KOMMUNE, P_LAT, P_LON, P_GENAU)
VALUES ('Mexiko', '99312', 'El Vergel', 'Zacatecas', 'Jerez', 'Jerez (Jerez De Garcia Salinas)', 22.5, -103, 4); |
AW: Wie bekomme ich einen performanten Firebird?
Ich habe mir das heruntergeladen, danke schon einmal. Ausführen kann ich das aber erst heute Abend, da ich momentan noch den Buchungsimport am Laufen habe - der wird noch ca. 6h dauern, ist nach 2h gerade bei 2 Mio. Dein Beispielbestand hat allerdings auch nur 900k records. Aber es wird reichen zum Testen, denn der Einbruch erfolgt ja schon nach wenigen 100k.
|
AW: Wie bekomme ich einen performanten Firebird?
Hallo,
was mich wundert, wenn die DB im async Mode geht es erst einmal erheblich schneller, das es erst einmal schneller ist ist ja in Ordnung, trotzdem habe ich die Vermutung das der FB Server nicht schnell genug auf der Platte schreiben kann. Ich hatte so einen Fall bei einem Kunden, super schnelle Platten, aber ab einer gewissen Menge an Daten ging die Plattenperfomance im Keller, konnte man auch mit einfachen Kopieren von Dateien nachstellen. Auch schon Antiviren Software, etc geprüft? Das die evtl. Irgendetwas ausbremsen? Gruß Jörg |
AW: Wie bekomme ich einen performanten Firebird?
Auf dem Server läuft keine. Wenn ich auf der WS ausschalte, gibt es keinerlei Unterscheid - hatte ich bereits probiert.
|
AW: Wie bekomme ich einen performanten Firebird?
ein bisschen mehr zur Hardware wäre nützlich
Raid ? wenn ja was für eines ggf Stripset size ? Ram Buffer auf dem Controller ? Größe ? ? ? ? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:43 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