Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Querystring präparieren (https://www.delphipraxis.net/201611-querystring-praeparieren.html)

Codehunter 7. Aug 2019 09:48

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

Querystring präparieren
 
Hallo!

Ich habe eine Stored Procedure, die ich (abhängig von Importlisten) u.U. viele tausende Male aufrufen muss. Bisher habe ich da immer TpFIBStoredProc verwendet und die Prozedurparameter mit ParamByName zugewiesen. Das wird aber in so großen Schleifen zum Flaschenhals.

Nun habe ich überlegt, den Querystring wie z.B.:
Code:
EXECUTE PROCEDURE MY_PROC(:Param1,:Param2,:Param3)
in einer Stringliste zu sammeln und dann über TpFIBScripter als EXECUTE BLOCK an die DB zu senden. Sowas hab ich an anderer Stelle schon mehrfach gemacht. Allerdings muste ich dort nur Integers als Parameter übergeben, weshalb ich mir das Präparieren gespart habe. Hier sind es jetzt aber Strings. Gibt es denn innerhalb der FIBplus-Lib eine Funktion, die obigen Query-String mit String-Parametern präparieren kann? Also die reine Stringverarbeitung, ohne das ganze Objekt- und Transaktionsgedöns. Also z.B. sowas in der Art (hier mit einem array of String):

Delphi-Quellcode:
LMyQueryStr := PrepString('EXECUTE PROCEDURE MY_PROC(:Param1,:Param2,:Param3)', [LMyParamStr1, LMyParamStr2, LMyParamStr3]);


Grüße
Cody

hoika 7. Aug 2019 10:09

AW: Querystring präparieren
 
Hallo,

Zitat:

nur Integers als Parameter übergeben, weshalb ich mir das Präparieren gespart habe. Hier sind es jetzt aber Strings.
Was ist denn hier der Unterschied?

Ich würde eher also Execute Procedure sammeln und in einem Block übergeben.#

AFIAK: SP's sind übrigens selber schon prepared, der Query-Plan liegt bereits vor.

Codehunter 7. Aug 2019 10:14

AW: Querystring präparieren
 
Zitat:

Zitat von hoika (Beitrag 1439900)
Ich würde eher also Execute Procedure sammeln und in einem Block übergeben.

Genau das ist das Ziel der Aktion. Einen EXECUTE BLOCK muss ich aber mit fertig formatierten Queries füllen, mit Named Params kann der nicht umgehen. Wie geschrieben, solange die Prozedur nur Integer-Parameter hat konnte ich das einfach mit Format() zusammenbasteln. Bei Strings und der ganzen Quotierung (Stichwort SQL Injection) ist mir das zu heikel.

jobo 7. Aug 2019 11:12

AW: Querystring präparieren
 
Ich bin mir nicht sicher, ob ich das richtig verstanden habe, aber ich glaube, mehr als Du "früher" gemacht hast, geht nicht.

willst du?:
block
EXECUTE PROCEDURE MY_PROC(:Param1,:Param2,:Param3);
EXECUTE PROCEDURE MY_PROC(:Param1,:Param2,:Param3);
EXECUTE PROCEDURE MY_PROC(:Param1,:Param2,:Param3);
endblock

und die unterschiedlich befüllen?
Dann musst Du m.E. auf die Parameterobjekte verzichten und Klartext eintragen.

Alternative (Idee)
Wenn es immer diese Prozedur ist(jedenfalls nicht ständig andere, also halbewegs feste Parameterliste), die in Schleife gerufen wird, dann eine FB Proc bauen, die diesen Aufruf in einer Loop macht und die Parameter in einer Extra Tabelle dafür eintragen.

Parameter für diese "Super SP" wäre ggF. ein Range, Flag oder Stichdatum für beschränkung der Parametertabelle.

MyRealName 7. Aug 2019 11:18

AW: Querystring präparieren
 
Warum nicht andersherum.
Kann denn die DB wissen, welche Liste du sendest ? Zum Bsp. Selbst durch ein query herausfinden und du machst in der stored proc eine FOR SELECT Schleife ?
Oder Du nimmst eine Global Temporary Table und füllst die mit Deiner Liste und dann machst Du das oben mit der FOR SELECT auf die GTT.

(GTT damit mehrere Benutzer das zur Not gleichzeitig könnten).

Codehunter 7. Aug 2019 11:19

AW: Querystring präparieren
 
Wenn ich es recht überlege, habe ich wohl schlicht einen Schritt zu weit gedacht. Eigentlich brauche ich ja nichts weiter als das Delphi-Firebird-Äquivalent zu mysqli_real_escape_string() bei PHP und Mysqli. Den Rest kann ich wie gehabt mit Format() erledigen.

Schokohase 7. Aug 2019 11:36

AW: Querystring präparieren
 
Warum keine Parameter?

AFAIK ist die Anzahl der Parameter nicht beschränkt.
Delphi-Quellcode:
queryStr := '';

for i := 0 to 1000 do
begin
  queryStr := queryStr + Format( 'EXECUTE PROCEDURE MY_PROC(:Param1_%0d,:Param2_%0d,:Param3_%0d);',[i] ) + sLineBreak;
 
  query.ParamByName( Format('Param1_%0d',[i])).Value := 'wert1';
  query.ParamByName( Format('Param2_%0d',[i])).Value := 'wert2';
  query.ParamByName( Format('Param3_%0d',[i])).Value := 'wert3';
end;

query.SQL.Text := queryStr;
query.Execute();
Kein SQL-Injection Problem

Codehunter 7. Aug 2019 12:07

AW: Querystring präparieren
 
Zitat:

Zitat von Schokohase (Beitrag 1439922)
Kein SQL-Injection Problem

Aber das Flaschenhalsproblem aus #1.

Schokohase 7. Aug 2019 12:29

AW: Querystring präparieren
 
Zitat:

Zitat von Codehunter (Beitrag 1439927)
Zitat:

Zitat von Schokohase (Beitrag 1439922)
Kein SQL-Injection Problem

Aber das Flaschenhalsproblem aus #1.

Aber das
SQL-Code:
EXECUTE PROCEDURE MY_PROC('wert1...ganz lang','wert2...ganz lang','wert3...ganz lang');
EXECUTE PROCEDURE MY_PROC('wert1...ganz lang','wert2...ganz lang','wert3...ganz lang');
EXECUTE PROCEDURE MY_PROC('wert1...ganz lang','wert2...ganz lang','wert3...ganz lang');
EXECUTE PROCEDURE MY_PROC('wert1...ganz lang','wert2...ganz lang','wert3...ganz lang');
EXECUTE PROCEDURE MY_PROC('wert1...ganz lang','wert2...ganz lang','wert3...ganz lang');
ist dann schneller als das
SQL-Code:
EXECUTE PROCEDURE MY_PROC(:p1_0,:p2_0,:p3_0);
EXECUTE PROCEDURE MY_PROC(:p1_1,:p2_1,:p3_1);
EXECUTE PROCEDURE MY_PROC(:p1_2,:p2_2,:p3_2);
EXECUTE PROCEDURE MY_PROC(:p1_3,:p2_3,:p3_3);
EXECUTE PROCEDURE MY_PROC(:p1_4,:p2_4,:p3_4);
mit Parametern?

Da sag ich mal nix mehr zu ...aber als kleiner Wink: Probiere es mal aus

jobo 7. Aug 2019 12:40

AW: Querystring präparieren
 
Ja, ausprobieren ist gut!

Ich denke, je größer der Loopcount, desto eher macht sich das bemerkbar.
Hunderte oder tausende von Aufrufen dauern dann halt mit Parameterbestückung etwas länger.

Mglw. ist das aber nur in der Theorie bemerkbar, weil idR die Größe eines Blocks auch beschränkt ist. Weiß nicht, wie das firebird handhabt.

Am Ende macht es wahrscheinlich keinen großen Unterschied. Dann kommt man an den Punkt, die SP selbst zu optimieren.

Schokohase 7. Aug 2019 12:47

AW: Querystring präparieren
 
Ich weiß nicht ob es jemandem aufgefallen ist:

Mein Ansatz zielt darauf ab die Aufrufe in einem Rutsch an den Server zu schicken, aber trotzdem mit Parametern.

Es wird also in einem Aufruf dieses Statement abgearbeitet:
SQL-Code:
EXECUTE PROCEDURE MY_PROC(:p1_0,:p2_0,:p3_0);
EXECUTE PROCEDURE MY_PROC(:p1_1,:p2_1,:p3_1);
EXECUTE PROCEDURE MY_PROC(:p1_2,:p2_2,:p3_2);
EXECUTE PROCEDURE MY_PROC(:p1_3,:p2_3,:p3_3);
EXECUTE PROCEDURE MY_PROC(:p1_4,:p2_4,:p3_4);
...
EXECUTE PROCEDURE MY_PROC(:p1_n,:p2_n,:p3_n);
und nicht n mal
SQL-Code:
EXECUTE PROCEDURE MY_PROC(:p1,:p2,:p3);

Codehunter 7. Aug 2019 13:30

AW: Querystring präparieren
 
Könnte es evtl. sein dass ihr übersehen habt, dass es hier nicht um FireDAC sondern um FIBplus geht? Da unterstützt TFIBQuery keine Multiline-Queries und TpFIBScripter keine benannten Parameter. Insofern endet das Ausprobieren in einem "Invalid token...".

Firebird 2.5 unterstützt nur recht kleine Blöcke, sodass ich bei dynamisch berechneter Blockgröße in diesem Fall zwischen 50 und 90 Queries in einem Rutsch absetzen kann. Ich habs jetzt testweise mal ohne "Injection-Schutz" mit einem schnöden Format() implementiert. Ggü. der vorigen Implementierung mit dem zeilenweisen Aufrufen der Storedproc ist die Laufzeit von knapp 21 Minuten auf 21 Sekunden gesunken (bitte keine Witze dazu, ich habe weder die Storedproc noch das DB-Design zu verantworten). Das korrelliert insofern mit der Anzahl Zeilen je EXECUTE BLOCK.

Am Rande bemerkt empfinde ich die Einschränkungen von Firebird ggü. z.B. MariaDB wie eine Eisenkugel am Bein. MariaDB/MySQL kann Multi-Row-INSERT, was mir hier den Aufruf der Storedproc erspart hätte. Gut, FB 2.5 ist schon älter, aber in 3.0 wurde es ja auch kaum besser. Gibts da chon Erfahrungen mit der 4.0?

jobo 7. Aug 2019 14:22

AW: Querystring präparieren
 
Zitat:

Zitat von Codehunter (Beitrag 1439954)
.. ist die Laufzeit von knapp 21 Minuten auf 21 Sekunden gesunken (bitte keine Witze dazu, ich habe weder die Storedproc noch das DB-Design zu verantworten).

Ich mache nie Witze!

Die Laufzeitänderung überrascht mich nun doch sehr, mit so einem starken Unterschied hätte ich nicht gerechnet. Nicht jedenfalls bei unter 100 Aufrufen.

Irgendwie scheint da noch was anderes im Spiel zu sein.

Codehunter 7. Aug 2019 15:48

AW: Querystring präparieren
 
Zitat:

Zitat von jobo (Beitrag 1439961)
Die Laufzeitänderung überrascht mich nun doch sehr, mit so einem starken Unterschied hätte ich nicht gerechnet. Nicht jedenfalls bei unter 100 Aufrufen.

Irgendwie scheint da noch was anderes im Spiel zu sein.

Auf jeden Fall. Zum Beispiel wurde konstruktionsbedingt nicht nur je Aufruf der Storedproc ein TFIBStoredProc-Objekt erzeugt und freigegeben sondern auch noch jeweils eine Transaktion gestartet und Committed. Zudem läuft der Client in einer VM, worunter die Netzwerkperformance zum DB-Server insbesondere bei vielen kleinen Paketen erfahrungsgemäß leidet. Typischer Fall von gewachsenen Strukturen. Aber aus einem Eselkarren macht man im Handstreich eben keinen Sportwagen sondern bestenfalls eine Postkutsche ;-)

EgonHugeist 17. Dez 2020 06:25

AW: Querystring präparieren
 
Hallo Cody,

schau da mal rein: https://zeoslib.sourceforge.io/viewt...?f=50&t=129484 ich habe for Zeos8 BatchArray bindings auf dem Component-Layer hinzugefügt.. Vielleicht interessiert's dich ja.

Codehunter 17. Dez 2020 10:58

AW: Querystring präparieren
 
Zitat:

Zitat von EgonHugeist (Beitrag 1479326)
Hallo Cody,

schau da mal rein: https://zeoslib.sourceforge.io/viewt...?f=50&t=129484 ich habe for Zeos8 BatchArray bindings auf dem Component-Layer hinzugefügt.. Vielleicht interessiert's dich ja.

Das ist jetzt ein seltsamer Zufall. Obwohl das Thema schon eine Weile zurück liegt, habe ich just gestern Abend das Projekt von damals wieder ausgebuddelt. Zwischenzeitlich habe ich in anderen Projekten ebenfalls an dem Problem gearbeitet.

Grundsätzlich ist Firebird 2.5 nicht unbedingt ein Glanzstück was Performance angeht. Einmal scheint der Netzwerk-Stack nicht die Wurst vom Brot zu ziehen und andererseits nutzt die alte Architektur moderne CPUs nicht allzu effizient. Daneben können Queries auch nicht beliebig groß werden sondern sind IMHO auf 1024 Bytes begrenzt. In FB 3.0 wurde das auch nur minimal angehoben und erst in der kommenden 4.0 soll es dann endlich auf "unbegrenzt" große Queries gebracht werden. Kannst du mit ZEOS eigentlich schon die aktuelle FB 4.0 konnektieren?

Anhand deines Beispiels aus dem Link:
Delphi-Quellcode:
Query.Params[0].AsBooleans[1] := True;
könntest du evtl. mal ein Beispiel-Query zeigen, wie das anzuwenden ist?

Frickler 17. Dez 2020 17:00

AW: Querystring präparieren
 
Zitat:

Zitat von Codehunter (Beitrag 1479344)
Daneben können Queries auch nicht beliebig groß werden sondern sind IMHO auf 1024 Bytes begrenzt. In FB 3.0 wurde das auch nur minimal angehoben und erst in der kommenden 4.0 soll es dann endlich auf "unbegrenzt" große Queries gebracht werden.

Ein bisschen mehr ist es schon: http://www.firebirdfaq.org/faq197/

Codehunter 17. Dez 2020 19:00

AW: Querystring präparieren
 
Bei FB 3.0 bin ich mir nicht ganz sicher, aber bei der 2.5 schon. Ich kann mich noch gut erinnern, ich hatte das mit den 64kB damals auch gelesen und den FIBScripter entsprechend auf 32kB (50% "Luft" für UTF-8) eingestellt. Dann locker fluffig einen Stapel INSERT-Queries rein gepackt und... Exception.

Ich habe dann die Blockgröße immer weiter reduziert. Reproduzierbar stabil lief das erst ab ca. 2000 Bytes. Mit "Luft" waren es dann 1024 Bytes. Womit sich der Benefit des FIBScripters gegen Null bewegte. Ob das jetzt eine Limitierung der FIBtools oder Firebird selbst ist, da bin ich überfragt.

Bei besonders breiten Tabellen kann es sogar passieren, dass nicht mal ein vollständiges INSERT in einen Query passt. Dann muss das aufgeteilt werden in ein INSERT und ein oder mehrere UPDATE.

Unnötig zu sagen, dass ich auf Firebird und FIBtools nicht grad gut zu sprechen bin. Wenn ich die Wahl habe, nehme ich MariaDB oder SQLite.

EgonHugeist 18. Dez 2020 05:51

AW: Querystring präparieren
 
Guten Morgähn,

Cody ich kenne die Komponenten nicht, jedoch sind mir diese Limitationen auch nicht bekannt. Ich würde mich Frickler anschließen auch für FB2.5. Die einzige Besonderheit, welche es zu beachten gilt, wenn das SQL Länger als High(Word) wird ist: Es darf kein #0 byte enthalten sein.

Zitat:

Zitat von Codehunter (Beitrag 1479344)
Anhand deines Beispiels aus dem Link:
Delphi-Quellcode:
Query.Params[0].AsBooleans[1] := True;
könntest du evtl. mal ein Beispiel-Query zeigen, wie das anzuwenden ist?

Nur mal so dahin geschmissen ohne Sinn und Zweck und ungetestet:
Code:
unit ZQueryBatchDML;

interface

uses ZConnection, ZDataSet;

procedure ExecuteQueryBatchInsert;

implementation

uses SysUtils;

procedure ExecuteQueryBatchInsert;
var Connection: TZConnection;
    Query: TZQuery;
    DMLidx: Integer;
    Succeeded: Boolean;
begin
  Connection := TZConnection.Create(nil);
  {assign everything to connect}
  Query := TZQuery.Create(nil);
  Query.Connection := Connection;
  Connection.Connect;
  try
    Connection.ExecuteDirect('CREATE TABLE DML_INSERT_DEMO('+
      'ID INTEGER NOT NULL,'+
      'NUM VARCHAR(32),'+
      'INSERT_TIMESTAMP DATETIME)');
    Connection.StartTransaction;
    Succeeded := False;
    try
      Query.SQL.Text := 'INSERT INTO DML_INSERT_DEMO VALUES (:ID,:NUM,:INSERT_TIMESTAMP)';
      Query.Params.BatchDMLCount := 10;
      for DMLidx := 0 to 9 do begin
        Query.Params[0].AsIntegers[DMLidx] := DMLidx +1;
        Query.Params[1].AsStrings[DMLidx] := IntToStr(DMLidx);
        Query.Params[2].AsDateTimes[DMLidx] := now;
      end;
      Query.ExecSQL;
      Assert(Query.RowsAffected = 10);
      Succeeded := True;
    finally
      if Succeeded
      then Connection.Commit
      else Connection.Rollback;
    end;
  finally
    Query.Free;
    Connection.Free;
  end;
end;

end.
Ist das nun verständlicher? Du kannst auch eine TZTransaction benutzen, wenn benötigt..

Zitat:

Zitat von Codehunter (Beitrag 1479344)
Kannst du mit ZEOS eigentlich schon die aktuelle FB 4.0 konnektieren?

Na klar, ich habe auch die neue (Seit FB3) OO_API eingebaut und auf den Stand der letzten FB4 Beta gebracht:
https://fossies.org/linux/Firebird/d...ng_OO_API.html

Codehunter 18. Dez 2020 11:55

AW: Querystring präparieren
 
Also wenn ich das richtig verstehe, ist die magische Zeile diese:
Delphi-Quellcode:
Query.Params.BatchDMLCount := 10;
Damit definierst du, wie viele (gleiche) Zeilen es gibt und mit dem
Delphi-Quellcode:
AsIntegers[DMLidx]
spricht man dann die jeweilige Zeile an?

Hintergrundinfo: Wir hängen immer noch bei FB 2.5 fest, weil wir in den Vendor-Lock-In getappt sind. Als DAC haben wir uns vor vielen Jahren für FIBplus bzw. FIBtools entschieden. Zu der Zeit gabs noch gar kein FireDAC usw. Dummerweise hat der Hersteller von FIBplus irgendwann jegliche Tätigkeit eingestellt. Bis D 10.2.3 lassen sie sich noch kompilieren, danach ist Feierabend. Wir haben zwar die Quellen, aber die sind doch sehr "speziell" und schwer zu warten.

Wir haben dann mal eine Art Benchmark gebaut um zu vergleichen, welches DAC wie schnell ist. Im Rennen waren FIBplus, FireDAC, UniDAC und ZEOS. Bei SELECT-Queries mit diversen JOINS usw. sowie anschließender Iteration war das Ergebnis:
  1. FIBplus
  2. FireDAC
  3. ZEOS
  4. UniDAC

Bei INSERT und UPDATE mit prepared Statements war es so:
  1. FIBplus
  2. ZEOS
  3. FireDAC
  4. UniDAC

Wobei ich betone, die Quellen für den Benchmark sind aus der Erfahrung mit FIBplus entstanden und das Datenbankmodell womöglich auch daraufhin optimiert ist. Die FIBtools sind halt speziell für Interbase und Firebird macht worden und bis heute unschlagbar was die Performance bei Single-Queries angeht.

Spannend ist jedoch die Frage, wie schaut das Ganze bei Batch-Queries und Random Access (wie es im Zusammenspiel mit Devexpress häufig vorkommt) aus. Und da scheinen die FIBtools brutal in die Knie zu gehen. Das scheint ein Designproblem zu sein, weil die FIBtools anscheinend zwischen zwei Queries viel Zeit mit Aufräumen verbringen.

Nun können wir nicht ewig bei FB 2.5 bleiben. Vermutlich wird dieser Zweig spätestens mit dem Erscheinen von FB 4.0 aus jeglichem Support fallen. Irgendwann kommt dann vllt. ein Windows-Update und beerdigt den 2.5er Zweig. Ein Projekt wie unseres migriert man aber auch nicht im Handstreich auf eine andere DB. Schon gar nicht, wenn damit auch ein Wechsel des DAC verbunden ist.

FireDAC, UniDAC und ZEOS sind alle Multi-Backend-fähig. Das wird wohl darauf hinaus laufen, eins von diesen zu wählen. FireDAC ist das performanteste von diesen, jedoch zusammen mit UniDAC auch wieder mit der Gefahr eines Vendor-Lock-in behaftet. UniDAC zudem noch mit einem großen Abstand das langsamste. Für mich hätte ZEOS durchaus einen gewissen Charme, nur bin ich nicht der der am Ende entscheidet.

EgonHugeist 18. Dez 2020 12:42

AW: Querystring präparieren
 
Zitat:

Zitat von Codehunter (Beitrag 1479470)
Also wenn ich das richtig verstehe, ist die magische Zeile diese:
Delphi-Quellcode:
Query.Params.BatchDMLCount := 10;
Damit definierst du, wie viele (gleiche) Zeilen es gibt und mit dem
Delphi-Quellcode:
AsIntegers[DMLidx]
spricht man dann die jeweilige Zeile an?

Ja so ist es.
Zitat:

Zitat von Codehunter (Beitrag 1479470)
Hintergrundinfo: Wir hängen immer noch bei FB 2.5 fest, weil wir in den Vendor-Lock-In getappt sind. Als DAC haben wir uns vor vielen Jahren für FIBplus bzw. FIBtools entschieden. Zu der Zeit gabs noch gar kein FireDAC usw. Dummerweise hat der Hersteller von FIBplus irgendwann jegliche Tätigkeit eingestellt. Bis D 10.2.3 lassen sie sich noch kompilieren, danach ist Feierabend. Wir haben zwar die Quellen, aber die sind doch sehr "speziell" und schwer zu warten.

Das is schade. War kein OpenSource, oder?

Zitat:

Zitat von Codehunter (Beitrag 1479470)
Wir haben dann mal eine Art Benchmark gebaut um zu vergleichen, welches DAC wie schnell ist. Im Rennen waren FIBplus, FireDAC, UniDAC und ZEOS. Bei SELECT-Queries mit diversen JOINS usw. sowie anschließender Iteration war das Ergebnis:
  1. FIBplus
  2. FireDAC
  3. ZEOS
  4. UniDAC

Soweit ich mich erinnere habt ihr das noch Zeos 7.2 gemacht... Ich denke da ist seit ich an der 8er Reihe arbeite noch Luft nach oben für Zeos.
Zitat:

Zitat von Codehunter (Beitrag 1479470)
Bei INSERT und UPDATE mit prepared Statements war es so:
  1. FIBplus
  2. ZEOS
  3. FireDAC
  4. UniDAC

Auch hier sehe ich Spielraum für noch bessere Benchmarks.


Zitat:

Zitat von Codehunter (Beitrag 1479470)
Wobei ich betone, die Quellen für den Benchmark sind aus der Erfahrung mit FIBplus entstanden und das Datenbankmodell womöglich auch daraufhin optimiert ist. Die FIBtools sind halt speziell für Interbase und Firebird macht worden und bis heute unschlagbar was die Performance bei Single-Queries angeht.

Spannend ist jedoch die Frage, wie schaut das Ganze bei Batch-Queries und Random Access (wie es im Zusammenspiel mit Devexpress häufig vorkommt) aus. Und da scheinen die FIBtools brutal in die Knie zu gehen. Das scheint ein Designproblem zu sein, weil die FIBtools anscheinend zwischen zwei Queries viel Zeit mit Aufräumen verbringen.

Nun können wir nicht ewig bei FB 2.5 bleiben. Vermutlich wird dieser Zweig spätestens mit dem Erscheinen von FB 4.0 aus jeglichem Support fallen. Irgendwann kommt dann vllt. ein Windows-Update und beerdigt den 2.5er Zweig. Ein Projekt wie unseres migriert man aber auch nicht im Handstreich auf eine andere DB. Schon gar nicht, wenn damit auch ein Wechsel des DAC verbunden ist.

FireDAC, UniDAC und ZEOS sind alle Multi-Backend-fähig. Das wird wohl darauf hinaus laufen, eins von diesen zu wählen. FireDAC ist das performanteste von diesen, jedoch zusammen mit UniDAC auch wieder mit der Gefahr eines Vendor-Lock-in behaftet. UniDAC zudem noch mit einem großen Abstand das langsamste. Für mich hätte ZEOS durchaus einen gewissen Charme, nur bin ich nicht der der am Ende entscheidet.

Cody ich kann zu den anderen Komponenten nicht viel sagen. FireDac kenne ich nur von der Emba-Hilfe. Wenn's aber um wirklich TOP-Performace geht: Schmeiß alle DataSet-Komponenten weg und nutze den ZDBC Layer. https://synopse.info/forum/viewtopic.php?id=5560

Wie man deutlich sehen kann schüttelt Zeos die UniDac und FireDac deutlich ab. Ich wüßte kein FrameWork, welches eine 2. Art des Zugriffs bietet außer Zeos. In meinen Projekten nutze ich DataSet's nur noch für GUI+DB-Komponenten. Ansonseten hab ich die DataSets beerdigt. Dank all der DBGrid und Field-kompatibilität kann man klar sagen: Desto schneller der Server, desto höher der Geschwindigkeitsverlust durch die DataSets. Da alle von T(Custom)Dataset ableiten, haben auch alle das gleiche Problem. Wenn ich Massen-DML/CRUDS's am Laufen habe, soll's doch richtig schnell gehen und der Server sollte das Nadelöhr sein... Ich war noch vor ein paar Jahren TDataSet-Fan.. Wie sich Dinge ändern können, wenn man sich Alternativen öffnet?!

Codehunter 18. Dez 2020 13:16

AW: Querystring präparieren
 
Zitat:

Zitat von EgonHugeist (Beitrag 1479479)
Das is schade. War kein OpenSource, oder?

Jetzt frag mich mal was leichteres. Der Code ist mittlerweile öffentlich zugänglich aber IMHO keineswegs als FOSS zu betrachten. Der ursprüngliche Anbieter (Devrace) hat sich irgendwann einfach in Luft aufgelöst, ohne Ankündigung oder Erklärung. Wo kein Kläger da kein Richter, aber formal dürften wohl nur ehemalige Lizenznehmer wie wir berechtigt sein, diese Quellen zu verwenden.

Zitat:

Zitat von EgonHugeist (Beitrag 1479479)
Soweit ich mich erinnere habt ihr das noch Zeos 7.2 gemacht... Ich denke da ist seit ich an der 8er Reihe arbeite noch Luft nach oben für Zeos.

Das ist gut möglich.

Zitat:

Zitat von EgonHugeist (Beitrag 1479479)
Wenn's aber um wirklich TOP-Performace geht: Schmeiß alle DataSet-Komponenten weg und nutze den ZDBC Layer. https://synopse.info/forum/viewtopic.php?id=5560

Das wäre wohl ein Fall für einen neuen Benchmark :-)

Zitat:

Zitat von EgonHugeist (Beitrag 1479479)
Wie man deutlich sehen kann schüttelt Zeos die UniDac und FireDac deutlich ab. Ich wüßte kein FrameWork, welches eine 2. Art des Zugriffs bietet außer Zeos.

IMHO ging Ansgar Becker bei HeidiSQL vor Jahren auch schon diesen Weg bzgl. dem Mysql-Konnektor. Dass das Weglassen diverser Abstraktion der Performance guttut, liegt ja in der Natur der Sache. Die spannende Frage dürfte sein, wie sich der Migrationsaufwand für Altprojekte gestaltet. Wenn man dann mit viel Aufwand doch wieder eine eigene Abstraktion bauen muss, steht man am Ende wieder da wo man vorher war. Bei neuen Projekten könnte das sicher eine Alternative sein.

mikhal 18. Dez 2020 13:24

AW: Querystring präparieren
 
Habt ihr auch die IBDAC von Devart statt der UniDAC getestet? Die sind auch speziell für Interbase / Firebird geschrieben und sollten neben einer besseren Performance noch einige Admin-Funktionalitäten mitbringen.

Gruß Mikhal

Codehunter 18. Dez 2020 13:57

AW: Querystring präparieren
 
Zitat:

Zitat von mikhal (Beitrag 1479484)
Habt ihr auch die IBDAC von Devart statt der UniDAC getestet? Die sind auch speziell für Interbase / Firebird geschrieben und sollten neben einer besseren Performance noch einige Admin-Funktionalitäten mitbringen.

Nein. UniDAC stand überhaupt nur deshalb für den Benchmark zur Verfügung, weil ich privat eine Lizenz dafür habe. Soweit ich weiß, deckt eine UniDAC-Lizenz nicht die spezialisierteren DACs von Devart ab. Die Trials sind der Website zufolge begrenzt was die Tabellenbreite angeht, daher nutzen die nix für den Benchmark. Und nur dafür 500 bzw. 700 Euro ausgeben und die Pro-Lizenz kaufen, ähm nö, das geht bei uns in der GL nicht durch.

EgonHugeist 18. Dez 2020 14:05

AW: Querystring präparieren
 
Zitat:

Zitat von CodeHunter
Das wäre wohl ein Fall für einen neuen Benchmark

Dem würde ich mit Freuden entgegensehen. Aber es sollte veröffentlicht werden, damit jeder sich seine eigen Meinung bilden kann. Ebenfalls wäre wüschenswert, dass das Benchmark nicht von TDataSets abhängt. Soll heißen das mORMot TSQLDBStatement/ISQLDBRows oder Zeos IZPreparedStatemnt/IZResultSet sollte in gleicher weise testbar sein, wie FireDac, IBX, UniDac etc.

Doch ich habe keine Zeit dafür, Arbeit + Zeos sind genug.

Vielleicht ist da ein Sportsmann, den es interessiert so etwas umzusetzen?

Zitat:

Zitat von CodeHunter
IMHO ging Ansgar Becker bei HeidiSQL vor Jahren auch schon diesen Weg bzgl. dem Mysql-Konnektor.

Ansgar hatte mal Zeos genutzt, da aber Zeos im Winterschlaf lag, was den Unicode-Support betraf, bis ich das mal mehr oder weniger gut gelöst hatte (bin rückblickend auf 7.1 nicht mehr stolz), hatte Ansgar Zeos verlassen(noch lange bevor ich ein Zeos-Dev-Member wurde), nutzt dennoch die DataSet's afaik.


Zitat:

Zitat von Mikhal
Habt ihr auch die IBDAC von Devart statt der UniDAC getestet? Die sind auch speziell für Interbase / Firebird geschrieben und sollten neben einer besseren Performance noch einige Admin-Funktionalitäten mitbringen.

Wenn die Frage an die mORMot Tests gerichtet war, welche ich verlinkt hatte, wäre die Antwort: Nein. Ich kann mir auch nicht vorstellen, daß Arnaud weiter Anstrengungen unternehemen wird weitere DB.pas DataSet-Descentants zu implementieren, da er es war, welcher mich auf das bottleneck TDataSet brachte. Das mORMot Framework ist bekannt für Hochgeschwindigkeit, sticht dabei DataSnap die Augen aus, somit würden weiter DAC-Treiber basierend auf db.pas nur noch via constribution bei ihm erscheinen. Aber warum das tun, wenns danach nicht besser wird...

Codehunter 18. Dez 2020 14:58

AW: Querystring präparieren
 
Zitat:

Zitat von EgonHugeist (Beitrag 1479489)
Doch ich habe keine Zeit dafür, Arbeit + Zeos sind genug. Vielleicht ist da ein Sportsmann, den es interessiert so etwas umzusetzen?

Das ist bei mir nicht anders. Selbst wenns eine Foundation gäbe für Delphi, Lazarus & Co., mehr Zeit kann einem keiner kaufen :cry:

Zitat:

Zitat von EgonHugeist (Beitrag 1479489)
Ansgar hatte mal Zeos genutzt, da aber Zeos im Winterschlaf lag, was den Unicode-Support betraf, bis ich das mal mehr oder weniger gut gelöst hatte (bin rückblickend auf 7.1 nicht mehr stolz), hatte Ansgar Zeos verlassen(noch lange bevor ich ein Zeos-Dev-Member wurde), nutzt dennoch die DataSet's afaik.

Das kann ich soweit bestätigen, er hat mir das selbe erzählt. Ich wurde vor langem Member bei HeidiSQL und musste meine Mitarbeit dort wg. chronischem Zeitmangel nach meinem Arbeitgeberwechsel auf Eis legen. Ich hatte dort insbesondere an einer neuen Benutzerrechte-Verwaltung für MySQL gearbeitet.

Zitat:

Zitat von EgonHugeist (Beitrag 1479489)
Wenn die Frage an die mORMot Tests gerichtet war, welche ich verlinkt hatte, wäre die Antwort: Nein. Ich kann mir auch nicht vorstellen, daß Arnaud weiter Anstrengungen unternehemen wird weitere DB.pas DataSet-Descentants zu implementieren, da er es war, welcher mich auf das bottleneck TDataSet brachte. Das mORMot Framework ist bekannt für Hochgeschwindigkeit, sticht dabei DataSnap die Augen aus, somit würden weiter DAC-Treiber basierend auf db.pas nur noch via constribution bei ihm erscheinen. Aber warum das tun, wenns danach nicht besser wird...

mORMot, das ist so ähnlich wie Tesla: Hat man mal gehört, soll sehr innovativ sein, aber so richtig traut man sich nicht ran :oops: Es ist manchmal echt zum Heulen. Es gibt viele Dinge die einem die Arbeit erleichtern könnten, aber es fehlt wg. dem Alltagsgeschäft die Zeit sich einzuarbeiten.

Codehunter 21. Dez 2020 12:36

AW: Querystring präparieren
 
Also die ZEOS 8.0 konnte ich nicht finden, aber die aktuelle 7.2.8 habe ich mir besorgt. Da ist ein kleines Fehlerchen in der ZDbcSqLiteResultSet.pas:
Delphi-Quellcode:
{$IFNDEF ZEOS_DISABLE_SQLITE} //if set we have an empty unit
uses
  {$IFDEF WITH_TOBJECTLIST_REQUIRES_SYSTEM_TYPES}
    System.Types, System.Contnrs // <--- HIER FEHLT EIN KOMMA
  {$ELSE}
    {$IFNDEF NO_UNIT_CONTNRS}Contnrs,{$ENDIF}
  {$ENDIF}
  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, ZClasses,
  ZSysUtils, ZDbcIntfs, ZDbcResultSet, ZDbcResultSetMetadata, ZPlainSqLiteDriver,
  ZCompatibility, ZDbcCache, ZDbcCachedResultSet, ZDbcGenericResolver,
  ZSelectSchema;

EgonHugeist 21. Dez 2020 16:53

AW: Querystring präparieren
 
Zitat:

Zitat von Codehunter (Beitrag 1479624)
Also die ZEOS 8.0 konnte ich nicht finden, aber die aktuelle 7.2.8 habe ich mir besorgt. Da ist ein kleines Fehlerchen in der ZDbcSqLiteResultSet.pas:
Delphi-Quellcode:
{$IFNDEF ZEOS_DISABLE_SQLITE} //if set we have an empty unit
uses
  {$IFDEF WITH_TOBJECTLIST_REQUIRES_SYSTEM_TYPES}
    System.Types, System.Contnrs // <--- HIER FEHLT EIN KOMMA
  {$ELSE}
    {$IFNDEF NO_UNIT_CONTNRS}Contnrs,{$ENDIF}
  {$ENDIF}
  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, ZClasses,
  ZSysUtils, ZDbcIntfs, ZDbcResultSet, ZDbcResultSetMetadata, ZPlainSqLiteDriver,
  ZCompatibility, ZDbcCache, ZDbcCachedResultSet, ZDbcGenericResolver,
  ZSelectSchema;

Habe ich im SVN: https://sourceforge.net/p/zeoslib/co...s/7.2-patches/ bereits gefixt. Ich teste die alten Version nur beim Merge und diese Compiler (mit dem define) habe ich wohl übersehen. Ein zwischen release ist in Arbeit.

Wegen der 8er Version:
gehe auf https://sourceforge.net/p/zeoslib/co...AD/tree/trunk/ und clicke "Download Snapshot" oben rechts. Es giebt noch kein bundle, da die Dokumentationen noch nicht fertig sind.
7.2.8 enthält nur Bug-Fixes (auch deine sind dabei -> MySQL UTF8-Bin war als TBytes interpretiert worden), soll heißen es wird auch nicht schneller..


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