Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi TIBDataSet - Performance (https://www.delphipraxis.net/97299-tibdataset-performance.html)

Nico80 8. Aug 2007 10:28

Datenbank: Interbase • Version: 7.1 • Zugriff über: IBX

TIBDataSet - Performance
 
Hallo an alle IBX-Experten,

habe eine Verständnisfrage.

Ich habe ein DataSet, um DS in die Datenbank einzufügen, zu aktualisieren und zu löschen.

Folgendes:

Delphi-Quellcode:
DataSet.SelectSQL.Text := 'SELECT...';
DataSet.InsertSQL.Text := 'INSERT...';
DataSet.UpdateSQL.Text := 'UPDATE...';
DataSet.DeleteSQL.Text := 'DELETE...';
Wenn ich jetzt 1000 DS einzeln aus der DB lese (also für jeden DS das DataSet neu öffne) kostet das paar Sekündchen.

Wenn ich nun die InsertSQL, UpdateSQL, DeleteSQL-Zuweisungen weglasse, habe ich beim Lesen der DS einen Performance-Gewinn um die Hälfte der Zeit.

Woran liegt das??

Bernhard Geyer 8. Aug 2007 10:35

Re: TIBDataSet - Performance
 
Vermutlich werden irgendwelche Parsingoperationen/Parameteraufbau im Hintergrund durchgeführt.

Noch mehr Performance bekommst du diesen ganzen Automatismus wegläßt und prepared Statements verwendest.

hoika 8. Aug 2007 10:54

Re: TIBDataSet - Performance
 
Hallo,

das DataSet.Open ruft das SelectSQL auf.
Steht dort etwas in der Art 'Select * From Table',
wird auf dem Server die komplette Tabelle geöffnet
und "zwischengespeichert" ,
du könntest ja jetzt per while not EOF
was Lesen wollen.

Das kann je nach Grösse der Tabelle schon etwas dauern.


Heiko

Hansa 8. Aug 2007 11:32

Re: TIBDataSet - Performance
 
Sieht so aus, als ob du den Dataset-Generator nicht benützt und somit für jeden Datensatz überflüssigerweise die Insert usw. Statements extra von Hand zusammenbaust. Kein Wunder, wenn das dauert.

mkinzler 8. Aug 2007 11:52

Re: TIBDataSet - Performance
 
Es spricht imho aber nichts dagegen das manuell zu machen, bzw. die automatisch erzeugten Statements per Hand zu optimieren.

Hansa 8. Aug 2007 12:13

Re: TIBDataSet - Performance
 
dafür spricht : ?? :mrgreen:

dagegen :
  • Überlistung des Servers könnte kontraproduktiv sein
  • Syntaxfehler wahrscheinlicher
  • vergessene Felder
  • Schreibfehler
  • kein Performance-Gewinn in Sicht
  • nach einem Close muss der Kram wieder neu gemacht werden
  • usw.

Normalerweise lässt man das Dataset mit Hilfe des Dataset-Generators die grundlegenden Statements (Insert, update...) erst mal erzeugen. Dem Programm sind dann die Tabellen-Felder erst mal bekannt. Und zwar alle ! Das hindert einen aber nicht flgendes zu machen :

Delphi-Quellcode:
Dataset.Close;
Dataset.SelectSQL.Text := 'SELECT ID,NR,NAME FROM TABLE1 WHERE NR < 100; // Einschränkung der Datenmenge
Dataset.Open;
while not Dataset.EOF do begin
...Bearbeitung der Daten
  Next
end;

mkinzler 8. Aug 2007 12:18

Re: TIBDataSet - Performance
 
Hallo Hansa,
du hast dir noch nie die automatsich erzeugten Statements angesehen oder?

Hansa 8. Aug 2007 12:39

Re: TIBDataSet - Performance
 
Doch, teste es doch selber. :mrgreen:

mkinzler 8. Aug 2007 12:44

Re: TIBDataSet - Performance
 
also wenn Tabellen einen Primärschlüssel haben braucht man nicht
delete from
SQL-Code:
<Tabelle<>where <Feld1>= ..., <Feld2>= ... ;
schreiben, da
SQL-Code:
delete from <Tabelle< where <pk> = ...;
reicht usw.

Hansa 8. Aug 2007 12:55

Re: TIBDataSet - Performance
 
Einfacher gehts mit :

Delphi-Quellcode:
Dataset.Delete;
Sofern der SQL-Generator so was in der Art erzeugt hat :

SQL-Code:
DELETE FROM
    ART
WHERE
        ID = :OLD_ID
Wer will, schreibt so was eben von Hand in seinen Source und nimmt damit dem Dataset die Arbeit ab. :zwinker:

mkinzler 8. Aug 2007 13:05

Re: TIBDataSet - Performance
 
das Problem ist das die Automatik dies nicht so erzeugt

Hansa 8. Aug 2007 13:14

Re: TIBDataSet - Performance
 
Du glaubst doch wohl nicht, dass ich das von Hand erzeugt habe ? :shock: Wer das in seinem Source sucht, wird in *.PAS nichts finden. Gespeichert wird das vom SQL-Generator in der DFM.

ahlzeitT :P

Nico80 9. Aug 2007 14:27

Re: TIBDataSet - Performance
 
Also wenn ich das richtig verstanden habe mache ich das mit prepared Statements wie folgt:

Delphi-Quellcode:
if not DataSet.Prepared then
  DataSet.Close,
  DataSet.SelectSQL := 'Select * from Tabelle where id=:Param';
  DataSet.Prepare;
end;

for i:= 0 to Count-1 do begin
  DataSet.Close;
  DataSet.ParamByValue('Param') := i;
  DataSet.Open;
 ...
end;
Das läuft auch viel schneller.
Wie mach ich das denn, wenn ich in der WHERE-Klausel unterschiedliche Parameter habe (auch Anzahl verschieden)?

Hansa 9. Aug 2007 18:47

Re: TIBDataSet - Performance
 
Zitat:

Zitat von Nico80
Also wenn ich das richtig verstanden habe mache ich das mit prepared Statements wie folgt:

Delphi-Quellcode:
if not DataSet.Prepared then
  DataSet.Close,
  DataSet.SelectSQL := 'Select * from Tabelle where id=:Param';
  DataSet.Prepare;
end;

Das ist halbrichtig, aber nicht ganz. :-D Grundlegende Vorgehensweise würde so aussehen :

Delphi-Quellcode:
  DataSet.Close,
  DataSet.SelectSQL := 'Select * from Tabelle where id=:Param';
  DataSet.ParamByName ('Param').AsString := edXY.Text; // sofern überhaupt Text für das Feld richtig
  DataSet.Open; // die Datenmenge steht nun zur Verfügung für Next, Prior, EOF usw.
"Prepared" ?? Wo soll da ein Vorteil liegen. Habe das noch nie gebraucht.

Zitat:

Zitat von Nico80
Wie mach ich das denn, wenn ich in der WHERE-Klausel unterschiedliche Parameter habe (auch Anzahl verschieden)?

Oben das (sowieso falsche SelectSQL umbauen. Da fehlt das .Text). Mit Close und Open das neu laufen lassen, Parameter anpassen usw. Wirds noch komplizierter, dann den einfacheren Weg über eine stored Procedure wählen.

Nico80 10. Aug 2007 09:48

Re: TIBDataSet - Performance
 
Zitat:

"Prepared" ?? Wo soll da ein Vorteil liegen. Habe das noch nie gebraucht.
Wenn du die gleiche Abfrage mehrmals nacheinander (z.b bei 1000 Datensätze) tätigst,
bringt das eine enorme Performancesteigerung im Sekundenbereich, da die Abfrage nicht jedesmal "vorbereitet" werden muss.

hoika 10. Aug 2007 10:09

Re: TIBDataSet - Performance
 
Hallo,

in der Regel halbiert sich die Ausführungszeit,
kommt aber auch immer darauf an, was gemacht wird,
also wie sehr das Netz belastet ist.

Sollte nicht auf FB2 ein Ausführungs-Cache
mit dabei sein, der das Preparen erübrigt?

Heiko

Hansa 10. Aug 2007 11:24

Re: TIBDataSet - Performance
 
Zitat:

Zitat von hoika
in der Regel halbiert sich die Ausführungszeit,..

Glaub ich nicht. Siehe auch hier :

http://entwickler-forum.de/showthread.php?t=19040

Sieht so aus, als könnten sogar die Nachteile überwiegen.

mkinzler 10. Aug 2007 11:28

Re: TIBDataSet - Performance
 
Nur weeil die BDE Sch... baut ist das doch kein Grund das mit anderen Komponenten zu verwenden.

Bernhard Geyer 10. Aug 2007 12:22

Re: TIBDataSet - Performance
 
Zitat:

Zitat von Hansa
Glaub ich nicht. Siehe auch hier :

http://entwickler-forum.de/showthread.php?t=19040

Sieht so aus, als könnten sogar die Nachteile überwiegen.

Bei Verwendung bei MySQL, Oracle und MySQL kann ich nur von sehr schönen Performance-Schub sprechen. Doppel so schnell i.d.R. zwar nicht aber mehr als merklich. Und BDE hab wir schon seit einiger Zeit nicht mehr aktiv im Einsatz.

Hansa 10. Aug 2007 15:19

Re: TIBDataSet - Performance
 
Zitat:

Zitat von Bernhard Geyer
Bei Verwendung bei MySQL, Oracle und MySQL kann ich nur von sehr schönen Performance-Schub sprechen...

Sind das vielleicht die falschen DBs, also die, die man besser nicht verwendet ? 2-mal MySQL braucht sowieso keiner. :mrgreen:

Muss sowieso noch einige Tables füllen und werde dafür prepare mal mitverwenden. Nur : wo soll das genau hin ? Vor das Open oder wohin ?

Bernhard Geyer 10. Aug 2007 15:30

Re: TIBDataSet - Performance
 
Zitat:

Zitat von Hansa
Zitat:

Zitat von Bernhard Geyer
Bei Verwendung bei MySQL, Oracle und MySQL kann ich nur von sehr schönen Performance-Schub sprechen...

Sind das vielleicht die falschen DBs, also die, die man besser nicht verwendet ? 2-mal MySQL braucht sowieso keiner. :mrgreen:

Muss sowieso noch einige Tables füllen und werde dafür prepare mal mitverwenden. Nur : wo soll das genau hin ? Vor das Open oder wohin ?

1 MySQL in MS SQL Server ändern :-)

Vor das Open und jeweils in der Schleife nur Schließen, Paramterwerte ändern und öffnen.

mkinzler 10. Aug 2007 16:49

Re: TIBDataSet - Performance
 
Je nach FB-Version geschieht der Prepare automatisch

Hansa 11. Aug 2007 13:18

Re: TIBDataSet - Performance
 
1851 (fette) Datensätze werden aus Textdatei zeilenweise gelesen, zerstückelt, den DB-Feldern zugewiesen, in die DB gepostet usw. Zeit mit prepare : 56 Sek., ohne Prepare : 55 Sek. Die eine Sekunde ist bloß Zufall, weil ich mir nur ganze Sek. anzeigen lasse.

Nächster Versuch : SELECT * FROM TABLEX, also lesen der ganzen Tabelle mit allen Feldern. Ob mit oder ohne Prepare, es ist nicht gelungen dies in einer Zeit > 1 Sek. zu machen.

Zumindest bei FB ist das Prepare IMHO völlig überflüssig. Allerdings der Vollständigkeit halber noch folgendes für die Millisekunden-Jäger : bei wesentlich höherer Anzahl an Datensätzen oder z.B. wenn ich mir den Inhalt der erstellten Tabelle z.B. in einem Stringgrid anzeigen lasse, dauert es mindestens ca. 5-10 mal so lange alle Daten zu sehen, sofern das Memo/Grid usw. laufend aktualisiert wird. Kein Witz ! Die Windows Anzeige ist lahm wie die Sau. :mrgreen: Sollen viele Daten angezeigt werden, dann habe ich mir angewöhnt, die später sichtbaren Sachen im Hintergrund zu bestücken und sie erst zu zeigen, wenn alles da ist. Für die User ist es schon ein Unterschied, ob sie 15 Sek. warten müssen, bis sie was sehen oder 1 Sek. Millisekunden sind denen allerdings völlig egal.

Bernhard Geyer 11. Aug 2007 17:12

Re: TIBDataSet - Performance
 
Zitat:

Zitat von Hansa
1851 (fette) Datensätze werden aus Textdatei zeilenweise gelesen, zerstückelt, den DB-Feldern zugewiesen, in die DB gepostet usw. Zeit mit prepare : 56 Sek., ohne Prepare : 55 Sek. Die eine Sekunde ist bloß Zufall, weil ich mir nur ganze Sek. anzeigen lasse.

Dann zeig mal den relevanten Code mit Prepare/Parameterbestückung/Execute. Da ich bei "meinen" DB's mit Prepares + Paramter einiges heraushole denke ich mal das du hier was falsch machst (Reichenfolge).

Hansa 11. Aug 2007 17:37

Re: TIBDataSet - Performance
 
Das ist ja kaum was :

Delphi-Quellcode:
// Memo1.Lines.add (TimeToStr (time));
  DS.Prepare;
  DS.open;
  WHILE NOT Eof (t) DO BEGIN
    i := i + 1;
//    Memo1.Lines.Add(IntToStr (i));
    DS.Insert;
    NR := LeseIntFeld5;  // Nr. aus Textzeile lesen
    DS.FindField ('NR').AsInteger := NR;

Prepare wirkt sich nicht aus. Zumindest so nicht. :mrgreen:

Bernhard Geyer 11. Aug 2007 17:44

Re: TIBDataSet - Performance
 
Scheinbar so nicht :-)

Ich würde folgendes machen:

Delphi-Quellcode:
DS.SQL.Text := 'INSERT INTO <Table>(FeldListe] VALUES(:Param1, :Param2)';
DS.Prepare;

while ...
begin
  DS.SQL.Parameters['Param1'].AsString := ...;

  DS.Execute;
end;

Hansa 11. Aug 2007 18:15

Re: TIBDataSet - Performance
 
Bernhard, wie das SQL-Insert aussehen soll, das weiß ja schon das Dataset. Das brauche ich also nicht noch von Hand in den Source zu schreiben. Execute gibts da nicht. Was soll ich jetzt da machen ? Habe das Prepare jetzt an allen (un)möglichen Stellen eingesetzt. Es wirkt sich sich in keinster Weise aus.

Bernhard Geyer 11. Aug 2007 20:34

Re: TIBDataSet - Performance
 
Evtl. mußt du mit dem "normalen" SQL-Property arbeiten da bei verwendung von DataSet.SelectSQL/UpdateSQL/... die Komponente einfach nicht fähig ist die Statements preparen zu lassen. Gibts eigentlich bei Interbase/Firebird die möglichkeit auf DB-Seite die angekommenen Statements zu loggen?

mkinzler 11. Aug 2007 20:37

Re: TIBDataSet - Performance
 
Zitat:

Gibts eigentlich bei Interbase/Firebird die möglichkeit auf DB-Seite die angekommenen Statements zu loggen?
Momentan mit Boardmitteln nicht.

Hansa 12. Aug 2007 13:28

Re: TIBDataSet - Performance
 
Doch geht mit Bordmitteln (Trigger). Am besten benutzt man dazu aber IBExpert (wird allerdings wohl nur mit Vollversion gehen). Da werden die Log-Trigger und ein paar Log-Tabellen halbautomatisch angelegt (Grundgerüst). In einer DB habe ich zumindest aus Tests übriggebliebene IBE$LOG... irgendwas rumliegen. :mrgreen:

mkinzler 12. Aug 2007 13:29

Re: TIBDataSet - Performance
 
Mit Triggern kann man aber keine Select-Queries abfangen. Die echten Serverseitigen Log-Tabellen wird erst noch kommen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:40 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 by Thomas Breitkreuz