Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Wie langsam ist Firebird über Internet wirklich? (https://www.delphipraxis.net/169309-wie-langsam-ist-firebird-ueber-internet-wirklich.html)

alleinherrscher 11. Jul 2012 12:03

Datenbank: Firebird • Version: 2.5 • Zugriff über: IB

Wie langsam ist Firebird über Internet wirklich?
 
Hi@all!

Ich weiß, dass es schon einige Themen zu Firebird und der Geschwindigkeit im Netzwerk gibt und dass Firebird bzw Interbase ziemlich viele kleine Datenpakete schickt, weshalb die Engine im Internet langsamer wird.

Ich habe hier ein Programm, das in der Firebird-DB ca 40 Abfragen macht. Dafür braucht das Programm 20 Sekunden übers Internet. Im Netzwerk geschieht die Abfrage nahezu sofort.

der Code sieht ungefähr so aus:

Delphi-Quellcode:
function TDataBaseConnection.IsDocumentInDB(CustomerID:integer;EMailDate:tDateTime):boolean;
var table: TIBTable;
    ta: TIBTransaction;
begin
   ta:=TIBTransaction.Create(nil);
  ta.DefaultDatabase:=DB;
  ta.Params.Add('read');
  table:=TIBTable.Create(nil);
  table.database:=DB;
  table.Transaction:=ta;
  table.TableName:='DOCUMENTS';
  table.filter:='CUSTOMER = '''+inttostr(CustomerID)+''' AND MODIFYDATE = '''+DateTimetoStr(EMailDate)+'''';
  table.Filtered:=true;
  table.Open;
  result:=(table.RecordCount>0);
  table.Close;
  freeandnil(table);
  freeandnil(ta);
end;
Dieser Code wird eben 40 mal aufgerufen. Ist dieser Code irgendwie sehr unperformant? Oder ist Firebird wirklich so extrem langsam über das Internet?
Gibt es andere DB's die die Aufgabe schneller erfüllen können (und wenn irgendwie möglich über TIBDatabase angesteuert werden können?)


Gruß und besten Dank,
Michael

tsteinmaurer 11. Jul 2012 12:26

AW: Wie langsam ist Firebird über Internet wirklich?
 
Ich würde mir angewohnen, dass man eine Art Profiling/Monitoring/Tracing verwendet, wenn es um Performanzthemen geht, damit man weiss, was der eigene Code so "verbricht".

Dein Code ist sehr Desktop-DB belastet. Kenn jetzt nicht die Implementierung im Hintergrund von IBX, aber ich könnte mir vorstellen, dass bei Verwendung von TIBTable/Filter/RecordCount im Worst-Case alle Datensätze zum Client transferiert werden.

Du willst ja im Wesentlichen überprüfen, ob basierend auf einem Filterkriterium, Datensätze existieren. Das kann mit SQL in einem SELECT gemacht werden, was dann am Server ausgeführt wird und letztendlich nur ein einzelner Wert zum Client übertragen wird.

Ja, Firebird's Remote-Protokoll ist geschwätzig und übers WAN weniger geeignet, aber in deinem Code steckt bei Verwendung einer Client/Server-Datenbank viel Verbesserungspotential.

Kommst du von einem Desktop-DB Background (Paradox, dBase, ...)?

alleinherrscher 11. Jul 2012 12:33

AW: Wie langsam ist Firebird über Internet wirklich?
 
Ne, ich habe nicht sehr viel Ahnung von Datenbanken im Allgemeinen und bin eher bei normaler Pascal-Programmierung zu Hause. Habe mir einfach über das Internet die entsprechenden Informationen zusammengesucht, um die Funktion zu schreiben. An anderen Stellen gehen ich auch über TDatasets, in denen ich mir die SQLInsert,Modify etc selber generiere. Aber auch die sind entsprechend langsam über WAN. Ist TIBTable sehr langsam? Allerdings sind in der entsprechenden Tabelle nur 5 Einträge gespeichert.

RWarnecke 11. Jul 2012 12:35

AW: Wie langsam ist Firebird über Internet wirklich?
 
Das schreit doch förmlich nach einer Stored Procedure oder einer View.

tsteinmaurer 11. Jul 2012 12:37

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Ne, ich habe nicht sehr viel Ahnung von Datenbanken im Allgemeinen
Schlecht, wenn man eine Datenbank-gestützte Anwendung schreiben muss. TIBTable ist für eine Client/Server-Anwendung nicht zu empfehlen.

alleinherrscher 11. Jul 2012 12:44

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von RWarnecke (Beitrag 1174306)
Das schreit doch förmlich nach einer Stored Procedure oder einer View.

Okay, das werde ich mal versuchen und dann das Ergebnis melden. Danke!

@tSteinmaurer Keine Ahnung zu haben ist immer schlecht, aber ich versuche dies gerade zu ändern. ;) Danke für den Hinweis mit tibtable. Ruft das Teil immer die ganze Tabelle ab?

RWarnecke 11. Jul 2012 12:50

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von alleinherrscher (Beitrag 1174309)
Ruft das Teil immer die ganze Tabelle ab?

Jepp. Eine Query ist hier besser.

tsteinmaurer 11. Jul 2012 12:52

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Ruft das Teil immer die ganze Tabelle ab?
Dafür kenne ich IBX zu wenig, aber könnte gut sein. Darum auch der Tipp in Bezug auf Monitoring etc. um von Anfang an etwas im Köcher zu haben.

shmia 11. Jul 2012 13:20

AW: Wie langsam ist Firebird über Internet wirklich?
 
Mit einer Query sieht das ganz grob so aus:
Delphi-Quellcode:
query.SQL.Text := 'SELECT COUNT(*) AS Anzahl FROM DOCUMENTS';
query.SQL.Add('WHERE CUSTOMER = '+QuotedStr(inttostr(CustomerID))+' AND MODIFYDATE = '+QuotedStr(DateTimetoStr));
ShowMessage(query.SQL.Text); // zum Debuggen die SQL-Abfrage anzeigen
query.open;
result := query.Fields[0].AsInteger <> 0;
Das lässt sich mit Parametern noch verbessern sollte so aber auch funktionieren.

Lemmy 11. Jul 2012 14:01

AW: Wie langsam ist Firebird über Internet wirklich?
 
Hi,

als Jeff Overcash die IBX vor über 10 Jahren veröffentlicht hat, hat er auch 2 Dinge klar gestellt:

1. TIBTable ist lediglich für die Abwärtskompatibilität da, d.h. sollte nur für Umstellungen (d.h. von DBase, Paradox usw. nach Interbase) verwendet werden und dann durch TIBQuery oder TIBDataSet ersetzt werden
2. IBX werden Firebird nicht unterstützen.

Die IBX funktionieren zwar meistens mit Firebird, aber es wird halt nicht offiziell unterstützt, d.h. kann auf Besonderheiten nicht eingehen.

Wenn es dir nur mal um den GEschwindigkeitsunterschied geht, nimm mal die UIB, bzw. wenn es später um "einfache" Datenbankanwendungen geht (d.h. Datenbank-Query-Datasouce-DBKomponente) dann auch die kommerziellen FIBplus oder IBDAC (gibts sicherlich auch Testversionen von denen). Die funktionieren auch mit den aktuellen Firebird-Versionen ohne "Tricks".

Wenn Du bei Firebird bleiben willst, gibts eine einfache Möglichkeit die Performance rasant zu steigern: Übertrag die Abfrage als Text auf einen "Anwendungsserver" der im lokalen Netz beim FBServer steht (oder direkt auf der selben Maschine läuft), führ die Abfrage dann dort "lokal" aus und übertrag das Ergebnis wiederum per TCP/IP Verbindung an den eigentlichen Client. Dazu hat sich auch mal einer Gedanken gemacht und ein Framework geschrieben, das find ich aber auf die schnelle nicht, oder doch:

http://leonardorame.blogspot.de/2009...work-part.html

da gehts zwar gleich um Objekte, aber auf eine vergleichbare Art und weise kannst Du ja auch ein Abfrageergebnis übertragen...

GRüße

Grüße

alleinherrscher 11. Jul 2012 14:39

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von shmia (Beitrag 1174314)
Mit einer Query sieht das ganz grob so aus:
Delphi-Quellcode:
query.SQL.Text := 'SELECT COUNT(*) AS Anzahl FROM DOCUMENTS';
query.SQL.Add('WHERE CUSTOMER = '+QuotedStr(inttostr(CustomerID))+' AND MODIFYDATE = '+QuotedStr(DateTimetoStr));
ShowMessage(query.SQL.Text); // zum Debuggen die SQL-Abfrage anzeigen
query.open;
result := query.Fields[0].AsInteger <> 0;
Das lässt sich mit Parametern noch verbessern sollte so aber auch funktionieren.

@Shima: Okay, die Benutzung von TIBQuery hat die Dauer der Abfrage von 20 Sekunden auf 5 Sekunden verringert. Das ist doch schonmal ein Anfang. Danke!!

@RWarnecke: Denkst du, dass Stored Procedures das ganze schneller machen, als die eine TIBQuery Abfrage von Shmia? Hier wird ja auch nur noch eine einzige Zahl an den Client übermittelt.

@Lemmy Danke für die Tipps. Ich werde Tibtable nicht mehr verwenden. Ich habe auch schon daran gedacht, einen TCP Server zu verwenden, der die DB lokal ansteuert. Habe die Idee aber zunächst verworfen, da der Server ein Debian System ist und ich dann den FPC verwenden müsste + sehr viel Arbeit für das kleine Programm.

Macht es sinn, in meiner Funktion, die 20 mal aufgerufen wird, jedes mal eine neue Transaction zu erstellen und diese hinterher wieder zu zerstören? Wäre es schneller/sinnvoller, die transaction nur einmal zu erstellen?

tsteinmaurer 11. Jul 2012 14:44

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zwei Optimierungstipps:

* Transaktionshandling aus der Routine rausziehen (wie du richtig erkannt hast), d.h. eine Transaktion starten, Abfragen ausführen, Transaktion mit einem Hard Commit comitten, fertig.
* Verwende eine Prepared-Query, die einmal Prepared wird, mit jedem Aufruf mit den neuen Parameterwerten befüllt and dann ausgeführt wird. So ersparst du dir den ständigen Traffic im Prepare-Schritt der Abfrage

mkinzler 11. Jul 2012 14:52

AW: Wie langsam ist Firebird über Internet wirklich?
 
Unter Umständen hilft es auch den Verkehr beim Zugriff übers Internet zu Tunneln ( ZeDeBee, stunnel).

alleinherrscher 11. Jul 2012 14:55

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von mkinzler (Beitrag 1174335)
Unter Umständen hilft es auch den Verkehr beim Zugriff übers Internet zu Tunneln ( ZeDeBee, stunnel).

Habe ich mit SSH/putty getestet, hat aber keine Zeit rausgeholt.

@tsteinmaurer Aber ein Commit brauche ich nur beim Ändern von Daten, richtig? Kann ich für verschiedene Lesevorgänge in der db die selbe transaction verwenden?

MrSpock 11. Jul 2012 15:07

AW: Wie langsam ist Firebird über Internet wirklich?
 
Grundsätzlich brauchst du ein Commit nur nach einem Schreibvorgang. Wichtig ist e aber eine Transaktion abzuschließen (commit oder rollback).

tsteinmaurer 11. Jul 2012 15:14

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Aber ein Commit brauche ich nur beim Ändern von Daten, richtig?
Nein. In Firebird läuft alles in Kontext von Transaktionen, auch lesende Zugriffe und auch diese Transaktion muss beendet (Commit/Rollback) werden.
Zitat:

Kann ich für verschiedene Lesevorgänge in der db die selbe transaction verwenden
Natürlich. Mit IBX stopelst dir das eben mit einer TIBTransaction zusammen, die dann von mehreren Query-Komponenten verwendet wird. Über den Isolation-Mode steuerst du dann was die einzelnen Abfragen im Kontext dieser Transaktion von anderen committed Transaktionen "mitbekommen".

Leider kümmern sich die Leute in der Regel kaum um das Transaktions-Management in der Client-Anwendung, ohne deren Auswirkungen zu kennen. Vor allem wenn man neu mit Firebird zu arbeiten beginnt. Das ist auch ein Hauptgrund für Performanceprobleme, wenn man z.B. langlaufende Transaktionen offen hat oder (unbewusst) in einem AutoCommit-Modus fährt, der für jede Abfrage automatisch eine neue Transaktion startet und diese automatisch auch wieder mit COMMIT RETAINING beendet. COMMIT RETAINING über eine längeren Zeitraum ohne regelmäßige HARD COMMITs kann für den Firebird Server eine Spaßbremse werden.

alleinherrscher 11. Jul 2012 15:29

AW: Wie langsam ist Firebird über Internet wirklich?
 
@tsteinmaurer: Okaydokay, die prepared-querys bringen nochmal eine Sekunde. Jetzt bauche ich noch das Commit ein. Bisheriger Code:
Delphi-Quellcode:
function TDataBaseConnection.IsEMailInDB(CustomerID:integer;EMailDate:tDateTime):boolean;
begin
if not assigned(IsEMailInDBQuery) then
 begin
   IsEMailInDBQuery:=TIBQuery.Create(nil);
   IsEMailInDBQuery.Database:=DB;
   IsEMailInDBQuery.Transaction:=ta;
   IsEMailInDBQuery.SQL.Text := 'SELECT COUNT(*) FROM DOCUMENTS';
   IsEMailInDBQuery.SQL.Add('WHERE CUSTOMER = :CUSTOMER AND MODIFYDATE = :MODIFYDATE');
   IsEMailInDBQuery.Prepare;
 end;

IsEMailInDBQuery.Params[0].AsInteger:=CustomerID;
IsEMailInDBQuery.Params[1].AsDateTime:=EMailDate;
IsEMailInDBQuery.open;
result := IsEMailInDBQuery.Fields[0].AsInteger <> 0;
IsEMailInDBQuery.Close;
end;
//edit: @Steinmaurer: Mit einem ta.commit; am Ende (nachdem IsEMailInDBQuery.Close) macht die Geschichte wieder ca. eine Sekunde langsamer?!

RWarnecke 11. Jul 2012 16:15

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von alleinherrscher (Beitrag 1174330)
@RWarnecke: Denkst du, dass Stored Procedures das ganze schneller machen, als die eine TIBQuery Abfrage von Shmia? Hier wird ja auch nur noch eine einzige Zahl an den Client übermittelt.

Ich bin noch nicht ganz dahinter gestiegen, warum Du diese Funktion so oft aufrufst. Eine Stored Procedure führt alles auf dem Datenbankserver aus und gibt dann das Ergebnis zurück. Das heißt es wird nicht x Mal der Select-Befehl an den Server geschickt.

alleinherrscher 11. Jul 2012 18:01

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von RWarnecke (Beitrag 1174349)
Zitat:

Zitat von alleinherrscher (Beitrag 1174330)
@RWarnecke: Denkst du, dass Stored Procedures das ganze schneller machen, als die eine TIBQuery Abfrage von Shmia? Hier wird ja auch nur noch eine einzige Zahl an den Client übermittelt.

Ich bin noch nicht ganz dahinter gestiegen, warum Du diese Funktion so oft aufrufst. Eine Stored Procedure führt alles auf dem Datenbankserver aus und gibt dann das Ergebnis zurück. Das heißt es wird nicht x Mal der Select-Befehl an den Server geschickt.

Ich habe n Dokumente (sagen wir charakterisiert durch einen String und eine DateTime - z.B. eine EMail) und möchte wissen, ob diese Dokumente schon in der Datenbank vorhanden sind.

mjustin 11. Jul 2012 19:49

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von MrSpock (Beitrag 1174338)
Grundsätzlich brauchst du ein Commit nur nach einem Schreibvorgang.

Andererseits muss man eine neue Transaktion auch dann beginnen, wenn man bei nur lesenden DB Zugriffen die zwischenzeitlich geänderten Daten sehen will. Die erste Aktion nach einem "COMMIT", "ROLLBACK" oder "CONNECT" beginnt eine neue Transaktion. Was man effektiv wann sieht, hängt noch vom Isolationslevel der Transaktion ab.

mjustin 11. Jul 2012 19:53

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von alleinherrscher (Beitrag 1174356)
Ich habe n Dokumente (sagen wir charakterisiert durch einen String und eine DateTime - z.B. eine EMail) und möchte wissen, ob diese Dokumente schon in der Datenbank vorhanden sind.

Das wäre einfach und firewallfreundlich über eine HTTP Abfrage an einen kleinen Anwendungsserver lösbar.

Die HTTP Anfrage würde als Body die Liste der Dokumente enthalten, und de HTTP Antwort je Dokument den aktuellen Status.

Dazu benötigt man nur eine (Indy) HTTP Server Komponente, die auf den DB Server zugreift. Für zusätzliche Sicherheit wie HTTPS oder Zugriffsberechtigungen kann man darüber noch einen Apache HTTP Server schalten, der als Proxy die Internetanfragen annimmt und an das Delphi Programm weiterleitet.

alleinherrscher 11. Jul 2012 20:15

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von mjustin (Beitrag 1174367)
Zitat:

Zitat von alleinherrscher (Beitrag 1174356)
Ich habe n Dokumente (sagen wir charakterisiert durch einen String und eine DateTime - z.B. eine EMail) und möchte wissen, ob diese Dokumente schon in der Datenbank vorhanden sind.

Das wäre einfach und firewallfreundlich über eine HTTP Abfrage an einen kleinen Anwendungsserver lösbar.

Die HTTP Anfrage würde als Body die Liste der Dokumente enthalten, und de HTTP Antwort je Dokument den aktuellen Status.

Dazu benötigt man nur eine (Indy) HTTP Server Komponente, die auf den DB Server zugreift. Für zusätzliche Sicherheit wie HTTPS oder Zugriffsberechtigungen kann man darüber noch einen Apache HTTP Server schalten, der als Proxy die Internetanfragen annimmt und an das Delphi Programm weiterleitet.

Huhu, ja okay. Das gesamte Projekt enthält aber mehr als diese (etwas zeitkritische) Abfrage. Ich habe schon mit idTCPServer (lan.fs) und idHTTP gearbeitet. Trotzdem würde ich gerne hier vermeiden, eine solche Lösung implementieren zu müssen, da der Server, auf dem die DB installiert ist, ein Debian Linux ist. Das ist vom Prinzip her kein Problem (mit Free Pascal könnte ich einen kleinen Server schreiben). Aber das wäre echt nur meine allerletzte Maßnahme. Ich glaube, es ist weniger Arbeit, den bereits bestehenden Code notfalls auf eine andere DB wie Postgresql umzubauen. Aber am liebsten würde ich bei Firebird bleiben.

Vom Prinzip handelt es sich bei den Dokumenten um E-Mails auf einem IMAP Server, die ich mit idIMAP4 abrufe und dann lokal speichern möchte.

Grüße,
Michael

IBExpert 11. Jul 2012 22:40

AW: Wie langsam ist Firebird über Internet wirklich?
 
Moin,

wie hier schon mehrfach erwähnt, bringt jedes execsql oder open immer diverse Datenpakete vom Client zum Server und zurück.
Auch einfach nur mit next durch die Datenmenge zu laufen erzeugt blockweise Traffic.

Da greift jeweils die Latenz, sprich wie lange dauert der Ping. Wenn dein Server auf localhost ist, dann merkst du das nicht,
im lokalen Netzwerk auch eher nicht, weil ping zeit 1ms o.ä., wenn dein Server über gute Leitung mit schneller Ping zeit
extern in irgendeinem Rechenzentrum erreichbar ist, dann geht pro Paket 15-20 ms drauf. Da sind 50 Pakete ca. eine Sekunde.
Ist dein server in Australien, dann sind 300-400ms schon ganz gute Werte, aber 50 Pakete ca. 15-20 Sekunden.

Bei jedem open und execsql kannst du die pingzeit schon mal mit 10 multiplizieren, auch jeder parambyname erhöht das ganze noch mal.

Es hilft also nur, die Anzahl Datenpakete möglichst zu minimieren, genau so machen das auch http Server: Du sendest einen Request
und der Webserver liefert dir einen unidirektionalen Datenstrom, den du lokal auswertest. Wenn du in einer Ajax Webanwendung
einen ähnlichen Quatsch programmierst und jede Zeile im Grid einzeln in eigenen requests abholst, dann läuft das genau so langsam.
Macht man aber bei Webanwendungen nicht freiwillig.

Man kann das auch mit Firebird minimieren, ich hatte dafür hier mal einen kleinen Denkanstoß veröffentlicht:
link

Vielleicht ist das für dich schon passend, die E-Mails, die du abholen willst, liegen ja sicherlich eh als Blob vor. Daher
konstruier dir einfach eine SP, wo du deinen Befehl selbst gestalten kannst und den als Blob parameter zum Server sendest.
Dann hol dir das Ergebnis in einem einzigen Blob zurück, mit von dir definierten Trennern, die du dann ggf lokal wieder
zum auseinandernehmen benutzen kannst. Das gleiche Format kannst du auch im Firebird Server zum senden benutzen:
Nichts hindert dich daran, den Quellcode von 100 E-Mails mit deinem Trenner zusammenzupacken und das als ein Blobparam an
die SP auf dem FBServer zu senden, der die dann lokal wieder mit deinem Trenner auseinander nimmt.
Die Geschwindigkeit ist dann eher durch die Bandbreite der Verbindung limitiert als durch die Ping Zeit.

Per UDF kannst du den Datenstrom dann serverseitig noch komprimieren und Clientseitig ggf mit der gleichen Funktion wieder
entpacken. Solche UDFs kannst du ggf mit Delphi für win32 oder xe2 auch für win64 FB Server in Pascal Code schreiben
(oder auch mit Lazarus, dann auch noch für Linux u.a., wir haben das für Kunden bereits mit lazarus gemacht).

Die Frage ist also eigentlich nicht wie langsam Firebird über das Internet wirklich ist, sondern bist du bereit, die
Möglichkeiten auszunutzen, um den maximalen Speed rauszuholen. Der Umweg über die Blob I/O Prozedur ist eigentlich nichts
anderes als das was Application Server machen, die als Middleware da zwischen gepackt werden. Damit fehlen dann bei Appserver
aber schnell Dinge wie echte Transaktionskontrolle oder du mußt ein weiteres Protokoll implementieren, was dir am ende nicht
wirklich Vorteile bringt. Wenn du das auf Basis der o.a. I/O SP machst musst du wenig neues lernen ....

alleinherrscher 12. Jul 2012 08:43

AW: Wie langsam ist Firebird über Internet wirklich?
 
Vielen Dank, IbExpert. :) Ihr habts echt drauf! Okay, dann werde ich mir mal ein bisschen was dazu durchlesen und mal versuchen, die Abfrage in einer Stored Procedure zu erledigen. Ich muss ja auch gar nicht den gesamten EMail-Quelltext übertragen...Zeitstempel und Absender sollten ja auch reichen.

Melde mich wieder, wenn ich was Lauffähiges präsentieren kann oder ich überhaupt nicht weiterkommen sollte.

Besten Dank,
Michael

hoika 14. Jul 2012 18:08

AW: Wie langsam ist Firebird über Internet wirklich?
 
Hallo,

das prepare bringt nur etwas,
wenn die Query mehrfach mit dem gleichen SQL-Text verwendet wird.
Hier bieten sich Parameter an.
Du erzeugst die Query aber immer wieder ?

Zitat:

Ich habe n Dokumente
Kennst du die Anzahl von n ?
Ist die endlich, kannst du die Abfrage ja dynamisch zusammenbauen.

Hier wäre ein Count(*) zusammen mit Group By möglich.


Heiko

IBExpert 15. Jul 2012 10:02

AW: Wie langsam ist Firebird über Internet wirklich?
 
bei langsamen Netzwerken mit hoher latenz (Pingzeit) sind parametrisierte querys eher kontraproduktiv, weil mit jedem parameterwert gesondert datenpakete hin uns her geschickt werden. Beim senden eines kompletten sqls wird nur das sql in einem Datenpaket zum server geschickt und dort prepared. was auf schnellen Netzwerken von Vorteil ist kann auf langsamen Netzwerken genau das Gegenteil sein.

alleinherrscher 6. Aug 2012 10:35

AW: Wie langsam ist Firebird über Internet wirklich?
 
Hallo nochmals. Haben das Problem jetzt mit Stored Procedures gelöst und die sind in der Tat wunderbar schnell, so dass ich nun mit der Geschwindigkeit meines Programms sehr zufrieden bin.

Problem: Ich habe das Abrufen der E-Mails in einem Thread ausgelagert. Innerhalb des Threads wird daher auch die folgende Funktion(s.u.)aufgerufen, die die Datenbank abfragen muss. Es kommt an der Stelle "IsEMailInDBQuery.Transaction:=ta;" zur AccessViolation - aber erst beim zweiten Aufrufen der Funktion.
Zusätzliche Informationen:
- Das Problem taucht nur auf, wenn das Programm mit einer DelphiXE2 Version innerhalb einer VirtualBox gedebugt wird.
- Das Object TDatabaseConnection befindet sich nicht innerhalb des Threads. Ich habe die Funktion IsEMailInDB daher testweise per Synchronize aufgerufen, was aber nichts an der AV ändert.


Delphi-Quellcode:
function TDataBaseConnection.IsEMailInDB_All(aEmailList:EMailList):IsEMailInDB_result;
var i:integer;
    str:string;
    ta: TIBTransaction;
begin

 ta:=TIBTransaction.Create(nil);
 ta.DefaultDatabase:=DB;

if not assigned(IsEMailInDBQuery) then
 begin
   IsEMailInDBQuery:=TIBQuery.Create(nil);
   IsEMailInDBQuery.Database:=DB;

   IsEMailInDBQuery.SQL.Text := 'SELECT * FROM IS_EMAIL_IN_DB(:STR)';
   IsEmailINDBQuery.Prepare;
 end;

 IsEMailInDBQuery.Transaction:=ta;

 str:='';
 for i := 0 to length(aEMailList)-1 do
     str:=str+inttostr(aEMailList[i].customerid)+','+datetimetostr(aEMailList[i].EmailDate)+',';

 str:=copy(str,1,length(str)-1);

 IsEMailInDBQuery.Params[0].AsString:=str;
 IsEMailInDBQuery.open;

 str := IsEMailinDBQuery.Fields[0].AsString;
 setlength(result,length(str));
 for i := 0 to length(str)-1 do
   result[i]:=(str[i+1]<>'0');

 IsEMailInDBQuery.Close;
 ta.free;
end;
Hat jemand eine Idee?

Lemmy 6. Aug 2012 11:51

AW: Wie langsam ist Firebird über Internet wirklich?
 
Hi,

schau bitte nach, ob der Zeiger auf die Objektstrutkur von IsEMailInDBQuery sich zwischen den ersten und zweiten Durchlauf unterscheidet. Bitte Kontrollier auch, ob Du IsEMailInDBQuery zwischen durch irgend wo freigibst ohne den Zeiger zu nillen...

alleinherrscher 6. Aug 2012 12:02

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von Lemmy (Beitrag 1177079)
Hi,

schau bitte nach, ob der Zeiger auf die Objektstrutkur von IsEMailInDBQuery sich zwischen den ersten und zweiten Durchlauf unterscheidet. Bitte Kontrollier auch, ob Du IsEMailInDBQuery zwischen durch irgend wo freigibst ohne den Zeiger zu nillen...

Huhu! Dies habe ich schon getan. Ich kann auch in der Quelltextzeile vor EMailAdressToCustomerIDQuery.Transaction:=ta auf IsEMailInDBQuery zugreifen und z.B. den ClassName ausgeben. Funktioniert wunderbar.

Lemmy 6. Aug 2012 12:38

AW: Wie langsam ist Firebird über Internet wirklich?
 
könntest Du dann mal die Stelle hier ändern bzw. die Transaction in der Query Nillen? Schau dir ggf. auch mal an was im Code bei der Query passiert, wenn DU ne Transaction setzt.


Delphi-Quellcode:
 IsEMailInDBQuery.Close;
 IsEMailInDBQuery.Transaction:=nil;
 ta.free;

alleinherrscher 6. Aug 2012 12:45

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von Lemmy (Beitrag 1177083)
könntest Du dann mal die Stelle hier ändern bzw. die Transaction in der Query Nillen? Schau dir ggf. auch mal an was im Code bei der Query passiert, wenn DU ne Transaction setzt.


Delphi-Quellcode:
 IsEMailInDBQuery.Close;
 IsEMailInDBQuery.Transaction:=nil;
 ta.free;

Hatte es schon mit freeandnil. Habe das Problem aber scheinbar gelöst, indem man auf XE2 Update 4 updatet. (auch ohne Synchronisation)

Trotzdem besten Dank für all eure hilfreichen Tipps!

tsteinmaurer 6. Aug 2012 12:53

AW: Wie langsam ist Firebird über Internet wirklich?
 
@alleinherrscher: Bei Multi-Threading Clients mit Firebird herrschen andere Gesetze und Dinge, die vorher gingen, funktionieren nun nicht mehr. Aus Firebird-Sicht gibt es hier ein paar Regeln, wie zum Beispiel: Jeder Thread eine eigene DB-Verbindung, kein Transaktions-Sharing zwischen Threads etc ...

Ich kenne jetzt dein Objektmodell nicht, aber ein Anfang bei dir wäre vermutlich im Email-Thread eine eigene, lokale TDatabaseConnection Instanz, die in keinster Weise in Abhängigkeit zu anderen Threads (auch nicht dem Main-Thread!) steht.

alleinherrscher 6. Aug 2012 13:22

AW: Wie langsam ist Firebird über Internet wirklich?
 
Zitat:

Zitat von tsteinmaurer (Beitrag 1177086)
@alleinherrscher: Bei Multi-Threading Clients mit Firebird herrschen andere Gesetze und Dinge, die vorher gingen, funktionieren nun nicht mehr. Aus Firebird-Sicht gibt es hier ein paar Regeln, wie zum Beispiel: Jeder Thread eine eigene DB-Verbindung, kein Transaktions-Sharing zwischen Threads etc ...

Ich kenne jetzt dein Objektmodell nicht, aber ein Anfang bei dir wäre vermutlich im Email-Thread eine eigene, lokale TDatabaseConnection Instanz, die in keinster Weise in Abhängigkeit zu anderen Threads (auch nicht dem Main-Thread!) steht.

Okay danke, wird gemacht. Besser ist das.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:51 Uhr.

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