Einzelnen Beitrag anzeigen

Perlsau
(Gast)

n/a Beiträge
 
#1

Optimierung Datenbankzugriff Firebird

  Alt 5. Mai 2013, 00:53
Moin allerseits,

ich greife mit den IBDac-Komponenten auf eine Firebird-Datenbank zu, in der bereits 16 Tabellen existieren. Beim Verbinden mit den Tabellen vergehen knapp 8 Sekunden, und mir kommt das doch ein wenig lang vor. Zum Projekt:

Auf einem Datenmodul sitzen eine TIBCConnection, 16 TIBCTable mit den dazugehörenden TIBCDataSource und zwei TIBCTransaction. In OnShow der Hauptform rufe ich meine Verbindungs-Funktion auf:
Delphi-Quellcode:
function TDatMod.Verbinden_Datenbank : Boolean;
begin
   Trennen_Datenbank;

   ConMain.Username := Adr_Types.URec.DB_User;
   ConMain.Password := Adr_Types.URec.DB_Pass;
   ConMain.Options.Role := Adr_Types.URec.DB_Role;
   ConMain.Server := 'localhost';
   ConMain.SQLDialect := 3;
   ConMain.LoginPrompt := False;
   ConMain.Options.Charset := 'UTF8';
   ConMain.Options.UseUnicode := True;

   IF Adr_Types.DB_Embedded THEN
   BEGIN
        ConMain.ClientLibrary := Adr_Types.URec.Pfad_Main + Adr_Types.Client_EmbedDLL;
        ConMain.Database := Adr_Types.URec.Pfad_Main + Adr_Types.DatenbankDateiName;
   END ELSE
   BEGIN
        ConMain.ClientLibrary := Adr_Types.URec.Pfad_Main + Adr_Types.Client_ServerDLL;
        ConMain.Database := Adr_Types.URec.Pfad_DB + Adr_Types.DatenbankDateiName;
   END;

   TRY
      ConMain.Connect;
   EXCEPT
      on e:exception DO ShowMessage('Fehler beim Verbinden mit der Datenbank: ' + e.Message);
   END;

   Result := ConMain.Connected;
end;
Das dauert meinen Messungen nach in der IDE im Debug-Mode 141 Millisekunden, dagegen als Exe Release gestartet nur noch 93 ms. Der Verbindungsaufbau zur Datenbank ist also nicht das Problem, wie ich oben schon andeutete. Die 16 TIBCTable-Komponenten auf Active := True zu setzen, dauert:
IDE Debug-Mode 8827 ms,
Exe Release 7155 ms.

Danach kommt das Setzen diverser Einstellungen von Tabellen, Sortierreihenfolgen usw., das dauert:
IDE Debug-Mode 2422 ms,
Exe Release 1828 ms.

Die Tabellen setze ich mit TIBCTable.Open aktiv:
Delphi-Quellcode:
function TDatMod.Verbinden_Tabellen: Boolean;
begin
     Result := False;

     TRY
        Tab_Benutzer.Open;
        Tab_Rechte.Open;
        Tab_Geschlecht.Open;

        ...

        Result := True;
     EXCEPT
        on e:exception DO ShowMessage('Fehler beim Verbinden mit den Tabellen: ' + e.Message);

     END;
end;
Von einem freundlichen Programmiererkollegen mit Win 7 und Radstudio XE2 erhielt ich folgende Testergebnisse, nachdem er mein Projekt auf seinem System getestet hatte:

*** Wie oben Win 7 32 Bit Debug
IF NOT DatMod.Verbinden_Datenbank THEN 70
IF NOT DatMod.Verbinden_Tabellen THEN 5129
Set_Einstellungen; 2327

*** Wie oben Win 7 64 Bit Debug
IF NOT DatMod.Verbinden_Datenbank THEN 58
IF NOT DatMod.Verbinden_Tabellen THEN 3867
Set_Einstellungen; 1847

*** Wie oben Win 7 32 Bit Release
IF NOT DatMod.Verbinden_Datenbank THEN 60
IF NOT DatMod.Verbinden_Tabellen THEN 5076
Set_Einstellungen; 2306

*** Wie oben Win 7 64 Bit Release
IF NOT DatMod.Verbinden_Datenbank THEN 64
IF NOT DatMod.Verbinden_Tabellen THEN 3855
Set_Einstellungen; 1777

*** Wie oben Win 7 32 Bit Debug IDE
IF NOT DatMod.Verbinden_Datenbank THEN 160
IF NOT DatMod.Verbinden_Tabellen THEN 5957
Set_Einstellungen; 2532
DatMod.ZweiteVerbindung; 55

*** Wie oben Win 7 64 Bit Release
IF NOT DatMod.Verbinden_Datenbank THEN 196
IF NOT DatMod.Verbinden_Tabellen THEN 3854
Set_Einstellungen; 1579
DatMod.ZweiteVerbindung; 48


Auf seinem Rechner, der ungefähr dieselbe Taktfrequenz und Ausstattung wie meiner hat (2x3 GHz, 4 GB Speicher) geht es also am schnellsten, wenn er eine 64-Bit-Anwendung erzeugt und mit einer 64-Bit-Firebird-Installation arbeitet. Leider kann ich nur 32-Bit-Anwendungen erzeugen, aber ich glaube, daß man das irgendwie optimieren kann, hab aber im Moment keinen blassen Schimmer, wo ich ansetzen könnte.

Der Eintrag DatMod.ZweiteVerbindung; in den letzten beiden Versuchen beschreibt die Zeit, die eine zweite Verbindung mit nur einer Tabelle benötigt (incl. Datenbankverbindung und Tabellen-Komponente auf aktiv setzen. Bei dieser zweiten Verbindung wurden keine Komponenten aufs Datenmodul geschoben, sondern dieselben im Create des Datenmoduls erst erzeugt:
Delphi-Quellcode:
procedure TDatMod.DataModuleCreate(Sender: TObject);
begin
   ConMainX := TIBCConnection.Create(DatMod);
   TransMainX := TIBCTransaction.Create(DatMod);
   Tab_LandX := TIBCTable.Create(DatMod);
   Dsrc_LandX := TIBCDataSource.Create(DatMod);
end;
Die Verbindung wird bei dieser Zweitverbindung erst hergestellt, wenn die erste Verbindung bereits besteht:
Delphi-Quellcode:
procedure TDatMod.ZweiteVerbindung;
begin
     ConMainX.Username := Adr_Types.URec.DB_User;
     ConMainX.Password := Adr_Types.URec.DB_Pass;
     ConMainX.Options.Role := Adr_Types.URec.DB_Role;
     ConMainX.Server := 'localhost';
     ConMainX.SQLDialect := 3;
     ConMainX.LoginPrompt := False;
     ConMainX.Options.Charset := 'UTF8';
     ConMainX.Options.UseUnicode := True;
     ConMainX.ClientLibrary := Adr_Types.URec.Pfad_Main + Adr_Types.Client_ServerDLL;
     ConMainX.Database := Adr_Types.URec.Pfad_DB + Adr_Types.DatenbankDateiName;
     ConMainX.DefaultTransaction := TransMainX;
     ConMainX.Connect;
     TransMainX.Active := True;
     Tab_LandX.Connection := ConMainX;
     Tab_LandX.TableName := 'LAND';
     Tab_LandX.KeyGenerator := 'GEN_LAND_ID';
     Tab_LandX.KeyFields := 'IDX_LAND';
     Tab_LandX.IndexFieldNames := '';
     Tab_LandX.Options.BooleanDomainFields := True;
     Tab_LandX.Open;
     Dsrc_LandX.DataSet := Tab_LandX;
     Dsrc_LandX.Enabled := True;
end;
Wäre es angesichts der Tatsache, daß die Zweitverbindung nur 48 ms inkl. einer Tabelle benötigt, hilfreich, alle Komponenten erst zur Laufzeit zu erzeugen? Ich könnte das ja mühevoll austesten, aber vielleicht hat ja bereits jemand diesen Versuch gemacht.

Was gäbe es sonst noch für Möglichkeiten, die Herstellung der Verbindungen zu beschleunigen?
  Mit Zitat antworten Zitat