Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Performance: Interbase vs. Firebird (https://www.delphipraxis.net/101087-performance-interbase-vs-firebird.html)

Nico80 8. Okt 2007 11:23

Datenbank: Firebird/Interbase • Version: 2.0.3/7.1 • Zugriff über: IBX/FIBPlus

Performance: Interbase vs. Firebird
 
Hallo an alle Datenbank-Experten,

ich mache gerade Performance-Tests (Insert, Update, Select, Delete mit 1000 Records) mit den Datenbanken Interbase und Firebird.
Als Zugriffskomponeten habe ich bisher IBX und FIBPlus verwendet.

Ergebnis:
Interbase ist deutlich schneller als Firebird.
Sogar ein Remote-Zugriff ist bei Interbase schneller als lokal bei Firebird.

Besonders das Prepare-Statement bei Interbase bringt eine erhebliche Performance-Steigerung.

Folgende Komponenten benutze ich für DB-Aktionen:
IBX:
Insert, Update, Delete: TIBSQL
Select: TIBDataSet
FIBPlus:
Insert, Update, Delete: TpFIBQuery
Select: TpFIBDataSet

Hat jemand gleiche oder andere Erfahrungswerte?

mkinzler 8. Okt 2007 12:50

Re: Performance: Interbase vs. Firebird
 
http://ibdeveloper.com/tests/

Nico80 8. Okt 2007 14:42

Re: Performance: Interbase vs. Firebird
 
Naja laut deren Testergebnisse ist Firebird schneller :?:
Das ist doch sehr merkwürdig...

mkinzler 8. Okt 2007 14:46

Re: Performance: Interbase vs. Firebird
 
Dort wird aber ein standardisierter Test verwendet und höchstwahrscheinlich nicht aus Delphi heraus.
Es könnte zusätzlich auch mit den Komponenten zusammenhängen. Welches ODS hatten deine verwendeten Datenbanken?

Nico80 8. Okt 2007 14:58

Re: Performance: Interbase vs. Firebird
 
Was meinst du mit ODS der Datenbanken?

mkinzler 8. Okt 2007 15:00

Re: Performance: Interbase vs. Firebird
 
ODS = On Disc Structure. Ist das Format der Datenbankdateistruktur. FB kann seine Vorteile nur ausspielen, wenn die passende neure ODS Version vorliegt. Ältere IB6-Datenbanken werden von FB nicht automatisch angepasst.

Nico80 8. Okt 2007 15:08

Re: Performance: Interbase vs. Firebird
 
Ich habe für meinen Test 2 neue Datenbanken angelegt.
Eine Datenbank besteht auch nur aus einer Tabelle.

Gruber_Hans_12345 8. Okt 2007 15:11

Re: Performance: Interbase vs. Firebird
 
also das thema würde mich auch mal interessieren und zwar

gibt es wo ein programm, mit dem ich einenleistungsindex der verschiedenen Datenbanken machen kann? - aber einen, der nicht einfach ein SQL Script abarbeitet, sondern einen, der von verschiedenen threads abfragen an die Datenbank schickt?

hintergrund ist, möchte gerne wissen, wieviel es bringt
  • multicore - Super Server vs ClassicServer bei FB
  • 2 GB, 3 GB, 4 GB RAM - was bringts
  • XP, Server 2000, Server 2003
  • 15k Harddisk <-> 10k Harddisk
  • ....

einfach zu sehen, wo kann ich bessere komponenten reinstecken, und was bringt das dann wirklich in einem stresstest.

Bin schon am überlegen, mir ein eigenes testprogramm zu erzeugen, am besten wäre es dann natürlich, wenn der server dann nicht isntalliert werden muß, sondern einfach als exe im selben dir gestartet wird (sollte doch gehen bei FB oder?)
und dieser mit ein paar unterschiedlichen Konfigurationen dann die testscripts ablaufen lässt

hat schon mal wer was in die richtung gemacht?

PS.: habs in diesen thread dazugeostet, da ich schon länger mit dem gedanken spiele, und durch diesen thread wieder dran denke ...

IBExpert 8. Okt 2007 19:04

Re: Performance: Interbase vs. Firebird
 
meine Tests basieren auf Delphi und Fibplus weil das die Plattform ist mit der IBExpert programmiert ist.
Zu einzelnen connections kann aich nichts sagen, aber auf Basis der IBExpert Demo DB dauert das erzeugen
und verarbeiten der prozedur initall mit dem parameter 10000:
auf ib75 und ib2007: ca 60 Sekunden
auf fb15: ca 50 Sekunden
auf fb20: ca 30 Sekunden
Das sind ca 800000 genau reproduzierbare Operationen, gut verteilt auf select, insert, update und delete.

Die Prozedur kann man mit wenigen Änderungen auch als ibeblock ablaufen lassen, dann wird jede Operation
gesonderte per Client API ausgeführt, also wie ein ganz normales Delphiprogramm das ohne Stored Procedure
auf dem Server auch machen würde.

auf ib75 und ib2007: ca 230 Sekunden
auf fb15: ca 210 Sekunden
auf fb20: ca 210 Sekunden
auf fb21: ca 140 Sekunden

Das war immer die gleiche Hardware und die DB wurde vor dem Test neu erstellt. Einen Geschwindigkeitsvorteil
kann ich aufgrund dieses Tests nicht erkennen, heisst aber nicht das andere Tests nicht Vorteile zeigen
können.

Gruß
Holger
www.firebird-conference.com

Nico80 9. Okt 2007 08:50

Re: Performance: Interbase vs. Firebird
 
Leider kann ich das überhaupt nicht nachvollziehen.

Poste mal mein Programmcode für einen Update mit TpFIBQuery...
die Prozedur mit 1000 mal aufgerufen...

Delphi-Quellcode:
  DataRec.LastUpdate := Now;
  FQueryUpdate.Transaction.StartTransaction;
  if (not FQueryUpdate.Prepared) then begin
    FQueryUpdate.SQL.Text := 'UPDATE table_test SET name=:name, number=:number, lastupdate=:lastupdate WHERE id=:id';
    FQueryUpdate.Prepare;
  end;
  FQueryUpdate.ParamByName('id').AsInteger := DataRec.Id;
  FQueryUpdate.ParamByName('name').AsString := DataRec.Name;
  FQueryUpdate.ParamByName('number').AsInteger := DataRec.Id;
  FQueryUpdate.ParamByName('lastupdate').AsDateTime := DataRec.LastUpdate;
  FQueryUpdate.ExecQuery;
  FQueryUpdate.Commit;
Mache ich rigendwas falsch?
Zeiten bei 1000 Datensätzen:
Interbase: ~ 224 ms
Firebird: ~ 1400 ms

IBExpert 9. Okt 2007 09:19

Re: Performance: Interbase vs. Firebird
 
schau dir noch mal an ob beide datenbanken auch forced writes true sind (bei firebird default, bei interbase nicht!).

Am besten beide auf forced writes=true stellen (in ibexpert unter services-database properties).
Verbesserungsvorschlag: Deine ganze schleife sollte am besten vor der schleife ein aml starttransaction
machen und nachher einmal commit (außerhalb der schleife) machen.

das ergibt dann bei gleicher forced writes Einstellung ein reales Bild

Gruß
Holger
www.firebird-conference.com

Nico80 9. Okt 2007 09:32

Re: Performance: Interbase vs. Firebird
 
Das Commiten für jeden DS habe ich bewusst gemacht.
Aber es scheint das das Schließen bzw. Commiten einer Transaktion bei Firebird länger braucht.

IBExpert 9. Okt 2007 09:37

Re: Performance: Interbase vs. Firebird
 
wie steht denn forced writes jeweils?

Gruß
Holger
www.firebird-conference.com

Nico80 9. Okt 2007 10:08

Re: Performance: Interbase vs. Firebird
 
Interbase ist Forced Writes nicht markiert
Bei Firebird ist es markiert...

Was bedeutet Forced writes?

Nun habe ich bei Firebird das Häkchen weggenommen und siehe da, die Zeiten haben sich verbessert.
Leider ist Interbase immer noch schneller.

Elvis 9. Okt 2007 10:10

Re: Performance: Interbase vs. Firebird
 
Zitat:

Zitat von Nico80
Das Commiten für jeden DS habe ich bewusst gemacht.

Das ist aber ein komplett unrealistisches Modell von den Anforderungen, die eine Applikation an ein DBMS stellt.
Keine sinnvoll entworfene Anwendung würde das machen, warum sollte dir das Ergebnis eines so unsinnigen Versuches eine Entscheidungshilfe sein?
Zitat:

Aber es scheint das das Schließen bzw. Commiten einer Transaktion bei Firebird länger braucht.
Sicher, dass beide Forced-writes aktiviert haben?
der Unterschied wäre höchstens minimal, bestenfalls kaum messbar. Bei realistischen Transaktionen wäre es wohl nicht messbar.

IBExpert 9. Okt 2007 10:30

Re: Performance: Interbase vs. Firebird
 
forced writes ist ein sicherheitsaspekt, der der wichtig ist.

forced writes aktiv=
beim commit werden alle geänderten datenpages in korrekter Reihenfolge so auf die Festplatte
geschrieben, das auch im Fehlerfall (serverabsturz) immer noch eine korrekte Datenbankdatei
auf der Festplatte zu finden ist und beim Neustart des Servers sofort weiter gearbeitet
werden kann

forced writes nicht aktiv=
beim commit werden die geänderten datenpages an das windows Betriebssystem übergeben, welches
dann bei Gelegenheit irgendwann mal die Daten auch auf die Festplatte schreibt. Das geschieht
aber in einer anderen Reihenfolge. Sollte dabei nun der Server ausfallen ist keineswegs
sichergestellt, das nach dem Neustart die DB benutzbar ist.

Was macht firebird anders?
Bei forced writes false wird trotzdem nach n operation oder n sekunden die datei in der richtigen
reihenfolge geschrieben. das kostet ggf Leistung. Das lässt sich bei Bedarf in der firebird.conf datei
anpassen.

Für einen Test sind 1000 Operationen mit 1000 Commits durchaus legitim, wenn das denn wirklich
so auftauchen wird. Bei derartigen minimaloperationen wie einem simplen Update ist das aber
eher nicht der Fall.

Wie schon gesagt: In meinem Test habe ich aber 800000 Operation in einer Transaktion gemacht und
da sieht fb2 wesentlich besser aus. Du solltest deine Testläufe auch erheblich vergrößeren, 1000
Operation lassen viel zu viel Raum für zufällige Einflüsse.

Ich würde aber ebenfalls immer versuchen mit den Transaktionen sparsam umzugehen. Das kostet nur
unnötig Performance. So etwas wie prepare und starttransaction sollte immer außerhalb einer
Schleife stehen.

Gruß
Holger
www.firebird-conference.com

Nico80 9. Okt 2007 11:14

Re: Performance: Interbase vs. Firebird
 
Habe mal die 4 DB-Aktionen gepostet.
Ich bin mir nicht sicher ob ich die Transaktionen richtig nutze?
Muss ich bei einem Select oder bei einer Stored Procedure die Transaktion commiten oder kann ich das DataSet einfach schließen?
Danke für die Hilfe...

Delphi-Quellcode:
function TDBFIBPlus2.GetPrimaryKey: Integer;
begin
  FStoredProcPrimaryKey.Transaction.StartTransaction;
  FStoredProcPrimaryKey.StoredProcName := 'GET_PRIMARYKEY';
  FStoredProcPrimaryKey.ExecProc;
  Result := FStoredProcPrimaryKey.Fields[0].AsInteger;
  FStoredProcPrimaryKey.Commit;
end;
//------------------------------------------------------------------------------
procedure TDBFIBPlus2.Insert(DataRec: TDataRec);
begin
  DataRec.Id := GetPrimaryKey;
  DataRec.LastUpdate := Now;
  FQueryInsert.Transaction.StartTransaction;
  if (not FQueryInsert.Prepared) then begin
    FQueryInsert.SQL.Text := 'INSERT INTO table_test (id, name, number, lastupdate)'+
                                 ' VALUES(:id, :name, :number, :lastupdate)';
    FQueryInsert.Prepare;
  end;
  FQueryInsert.ParamByName('id').AsInteger := DataRec.Id;
  FQueryInsert.ParamByName('name').AsString := DataRec.Name;
  FQueryInsert.ParamByName('number').AsInteger := DataRec.Id;
  FQueryInsert.ParamByName('lastupdate').AsDateTime := DataRec.LastUpdate;
  FQueryInsert.ExecQuery;
  FQueryInsert.Commit;
end;
//------------------------------------------------------------------------------
function TDBFIBPlus2.Select(Id: Integer): TDataRec;
begin
  Result := nil;
  FDataSetSelect.AutoCommit := True;
  if (not FDataSetSelect.Prepared) then begin
    FDataSetSelect.Close;
    FDataSetSelect.SelectSQL.Text := 'SELECT * FROM table_test where id=:id';
    FDataSetSelect.Prepare;
  end;

  FDataSetSelect.Close;
  FDataSetSelect.ParamByName('id').AsInteger := Id;
  FDataSetSelect.Open;

  if (not FDataSetSelect.IsEmpty) then begin
    Result := TDataRec.Create;
    Result.Id        := Id;
    Result.Name      := FDataSetSelect.FieldValues['name'];
    Result.Number    := FDataSetSelect.FieldValues['number'];
    Result.LastUpdate := FDataSetSelect.FieldValues['lastupdate'];
  end;
end;
//------------------------------------------------------------------------------
procedure TDBFIBPlus2.Update(DataRec: TDataRec);
begin
  DataRec.LastUpdate := Now;
  FQueryUpdate.Transaction.StartTransaction;
  if (not FQueryUpdate.Prepared) then begin
    FQueryUpdate.SQL.Text := Format('UPDATE table_test SET name=:name, number=:number, lastupdate=:lastupdate WHERE id=:id',[]);
    FQueryUpdate.Prepare;
  end;
  FQueryUpdate.ParamByName('id').AsInteger := DataRec.Id;
  FQueryUpdate.ParamByName('name').AsString := DataRec.Name;
  FQueryUpdate.ParamByName('number').AsInteger := DataRec.Id;
  FQueryUpdate.ParamByName('lastupdate').AsDateTime := DataRec.LastUpdate;
  FQueryUpdate.ExecQuery;
  FQueryUpdate.Commit;
end;
//------------------------------------------------------------------------------
procedure TDBFIBPlus2.Delete(DataRec: TDataRec);
begin
  FQueryDelete.Transaction.StartTransaction;
  if (not FQueryDelete.Prepared) then begin
    FQueryDelete.SQL.Text := 'Delete FROM table_test where id=:id';
    FQueryDelete.Prepare;
  end;
  FQueryDelete.ParamByName('id').AsInteger := DataRec.Id;
  FQueryDelete.ExecQuery;
  FQueryDelete.Commit;
end;
//------------------------------------------------------------------------------

Nico80 9. Okt 2007 11:22

Re: Performance: Interbase vs. Firebird
 
@mkinzler
ODS-Version: Interbase 11.1
Firebird 11.0

laut IBExpert

IBExpert 9. Okt 2007 12:27

Re: Performance: Interbase vs. Firebird
 
wie schon gesagt, wenn du auf Performance wert legst, dann lege dein starttransaction und commit außerhalb der schleifen.

weiterhin wenn du getprimary key schon umständlicherweise extra abfragst, um den dann wieder hinzuschicken, dann mach
das in der insert transaktion. Einfacher (jedenfalls bei firebird): mach auf der Tabelle einen Autoincrement Trigger
(geht in IBExpert im Tabelleneditor durch doppelklick auf das pk feld unter autoincrement), so das der wert von
einem generator vergeben wird. (geht aber auch ohne ibexpert)
create generator id;

create table test
(id integer not null primary key,
bez varchar(80));

create trigger test_bi for test
active before insert position 0
as
begin
if (new.id is null) then
new.id = gen_id(id,1);
end;

Bei deinem Insert kannst du mit der returning anweisung diesen dann auch lesen

INSERT INTO TEST(BEZ) VALUES (:BEZ) returning ID;

(geht aber nur bei firebird >=2, nicht bei interbase)

damit kann der insert in einem sql abgehakt werden und brauch nicht noch weitere befehle, du
kannst aber trotzdem den vergebenen Wert auslesen.

und außerdem: wer manuell einen prepare macht, der sollte irgendwann auch den unprepare machen.
der belegt sonst speicher im server. Ist bei wenigen Datasets zwar fast egal, wird aber später mit
mehreren immer schwieriger, das im Griff zu haben. Den unprepare in der Schleife zu machen wäre
jetzt aber denkbar ungeschickt.

und noch was: ich hoffe deine get_primarykey prozedur benutzt zumindest einen generator und nicht
irgendeinen Tabelleninhalt, sonst wird dir das irgendwann im netzwerkbetrieb probleme machen.

Gruß
Holger
www.firebird-conference.com

Nico80 9. Okt 2007 12:41

Re: Performance: Interbase vs. Firebird
 
Das mit dem StartTransaction ist mir klar geworden...

Soll auch ein "Worst Case"-Test sein ;-)

Zitat:

und noch was: ich hoffe deine get_primarykey prozedur benutzt zumindest einen generator und nicht
irgendeinen Tabelleninhalt, sonst wird dir das irgendwann im netzwerkbetrieb probleme machen.
Jawohl...

Hansa 9. Okt 2007 18:59

Re: Performance: Interbase vs. Firebird
 
Zitat:

Zitat von IBExpert
meine Tests basieren auf Delphi und Fibplus... weil das die Plattform ist mit der IBExpert programmiert ist.

Gut zu wissen. Das ist auch meine. :mrgreen:

Das mit den forced writes lässt mir allerdings jetzt keine Ruhe. Wo soll das sein ? Geschwindigkeitsprobleme sind zwar hier noch nicht aufgetaucht, aber die Konsistenz der DB ist immer wichtig.

IBExpert 9. Okt 2007 19:19

Re: Performance: Interbase vs. Firebird
 
? was meinst du mit "wo soll das sein?"
Die Einstellung kann man mit ibexpert und services-database properties oder über gfix anpassen.



Gruß
Holger
www.firebird-conference.com

Hansa 9. Okt 2007 19:28

Re: Performance: Interbase vs. Firebird
 
Ahso. Die DB muss also jeweils so eingerichtet sein ? Weil, es nützt ja nichts, wenn ich das in IBExpert so einstelle und mein eigenes Programm nichts davon weiß. Oder kann man die DB mit IBExpert dementsprechend komplett umstellen ?

IBExpert 9. Okt 2007 19:35

Re: Performance: Interbase vs. Firebird
 
ja, das ist ein Attribut der Datenbank und gillt immer so wie es zuletzt eingestellt wurde.
den Client interessiert das nicht, nur der Server reagiert dann beim Schreiben der Datei anders.

Gruß
Holger
www.firebird-conference.com

mkinzler 28. Mai 2010 05:28

Re: Performance: Interbase vs. Firebird
 
Einige themenfremde Beiträge wurden hierhin ausgelagert

mjustin 28. Mai 2010 06:23

Re: Performance: Interbase vs. Firebird
 
Zitat:

Zitat von Gruber_Hans_12345
gibt es wo ein programm, mit dem ich einenleistungsindex der verschiedenen Datenbanken machen kann? - aber einen, der nicht einfach ein SQL Script abarbeitet, sondern einen, der von verschiedenen threads abfragen an die Datenbank schickt?

Apache JMeter ist ein (kostenloses) Tool für genau diesen Zweck, nicht nur für Datenbankleistungstests.

Die Abfragen sendet JMeter in konfigurierbaren Intervallen und mit einstellbarer Anzahl von Clients (Threads). Die Ergebnisse werden dann mit den üblichen statistischen Angaben aufbereitet. Das Erstellen der Tests erfolgt über ein komfortables GUI.

hoika 28. Mai 2010 07:17

Re: Performance: Interbase vs. Firebird
 
Hallo,

Zitat:

Muss ich bei einem Select oder bei einer Stored Procedure die Transaktion commiten oder kann ich das DataSet einfach schließen?
Jede Aktion läuft in einer ransaktion (ob man es will oder nicht).

Warum wir aber das Ermitteln der neuen ID in einer eigenen Transaktion gemacht ?

Ausserdem wurde dir doch schon gesagt,
dass in der Realität nie 1000 Einträge mit je einer Transaktion in eine DB gemacht werden.
Warum änderst du das nicht ?

Dein Test ist einfach unrealisitisch.

Das sieht jetzt etwa so aus: "Auto 1 fährt im 1. Gang schneller als Auto 2."


Heiko

mkinzler 28. Mai 2010 07:28

Re: Performance: Interbase vs. Firebird
 
Ein etwas hinkender aber erklärender Vergleich:
Du hast Hundert Briefe bei der Post abzugeben.
Variante 1: Du fährst 100 mal zu Post und wirfst je einen ein. ( Eine Transaktion pro Insert = 100 Transaktionen)
Variante 2: Du faährst 1 mal hin und wirfst alle 100 Briefe ein ( Eine Transaktion für alle Inserts)

Rate mal was schneller ist. :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:21 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