Delphi-PRAXiS
Seite 3 von 7     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Wie bekomme ich einen performanten Firebird? (https://www.delphipraxis.net/180125-wie-bekomme-ich-einen-performanten-firebird.html)

Union 24. Apr 2014 18:00

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;

Dejan Vu 24. Apr 2014 21:45

AW: Wie bekomme ich einen performanten Firebird?
 
Oh. Nett. Danke.

Perlsau 25. Apr 2014 06:21

AW: Wie bekomme ich einen performanten Firebird?
 
Zitat:

Zitat von Union (Beitrag 1256824)
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....

Stimmt, die SQL-Dialekte sind nicht kompatibel :? Umgekehrt geht's aber schon ... glaube ich ... ungetestet :oops:

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:
    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
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.

mkinzler 25. Apr 2014 06:51

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:
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;
Testexport in externe Datei:
SQL-Code:
INSERT INTO _IMPORT
    SELECT <Felder vorhande Tabelle>, ascii_char(13) || ascii_char(10) FROM <vorhandene Tabelle>;
Import:
SQL-Code:
INSERT INTO <geleerte Tabelle/neue Tabelle im identischer Struktur>
  SELECT <Felder ohne CRLF> from _IMPORT;

Union 25. Apr 2014 06:55

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:
gfix -write async
auf die Datenbank losgelassen habe. Daraufhin wurden die 50000 Testdatensätze in 50 Sekunden geschrieben.

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.

Perlsau 25. Apr 2014 06:59

AW: Wie bekomme ich einen performanten Firebird?
 
Hab gleich einen Arzttermin und daher keine Zeit mehr. DB und SQL-Datei kann man sich dort herunterladen.

RWarnecke 25. Apr 2014 07:03

AW: Wie bekomme ich einen performanten Firebird?
 
Zitat:

Zitat von Union (Beitrag 1256883)
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?

Suche mal nach dem Forum-Mitglied IBExpert, der hat hier im Forum schon des öfteren was zu Firebird und Performance geschrieben und in seinen Beträgen auch einige Links zu anderen Seiten gesetzt, wo es auch über das Thema Performance und Firebird ging.

Union 25. Apr 2014 09:07

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.

tsteinmaurer 25. Apr 2014 09:09

AW: Wie bekomme ich einen performanten Firebird?
 
Welche Art von Commit machst du?

tsteinmaurer 25. Apr 2014 09:11

AW: Wie bekomme ich einen performanten Firebird?
 
Verwendest du auch die üblichen Praktiken wie Prepared Statements etc.?


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:07 Uhr.
Seite 3 von 7     123 45     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz