Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Daten Schleife schneller machen (https://www.delphipraxis.net/58064-daten-schleife-schneller-machen.html)

robby3 30. Nov 2005 21:19

Datenbank: dBase • Zugriff über: Query

Daten Schleife schneller machen
 
Hei ich brauche eure Hilfe
kann mir jemand einen Tipp geben wie ich meine Routine schneller machen kann.
Ich möchte in einer Datenbank den Inhalt Lagerb von Stueck abziehen.
Hier mein Code :?: :wink:

Delphi-Quellcode:
procedure TWAusgang.Button6Click(Sender: TObject);
begin
if Data.TableStueckliste.active= false then exit;
try
i2:= StrToInt(edit1.text);
except
Showmessage('Keine gültige Zahl im Textfeld!');
exit;
end;
for i1:= 1 to i2 do
begin

Data.tableLager.indexname:='pos';
 data.tableCopy.active:=true;  
Data.TableStueckliste.first;
Data.TableCopy.first;
 
while not Data.tableCopy.Eof do begin
Data.TableCopy.edit;
 Data.TableCopy.fieldByName('lagerb').AsInteger :=
  Data.TableCopy.fieldByName('lagerb').AsInteger-
  Data.TableCopy.fieldByName('stueck').AsInteger;
  Data.TableCopy.post;

  Data.TableCopy.next;

   end;
end;

supermuckl 30. Nov 2005 22:38

Re: Daten Schleife schneller machen
 
eventuell kann das ja die datenbank schon?
mit einem tollen query kannste das dann superschnell machen LASSEN

Jelly 30. Nov 2005 22:44

Re: Daten Schleife schneller machen
 
Zitat:

Zitat von supermuckl
eventuell kann das ja die datenbank schon?
mit einem tollen query kannste das dann superschnell machen LASSEN

Also so toll ist der SQL Befehl nun aber wahrlich nicht, und auch nicht unbedingt Datenbankabhängig.

SQL-Code:
update TabellenName set lagerb=lagerb-stueck
Das Ganze in eine TQuery Komponente in die SQL Eigenschaft gelegt und mit
Delphi-Quellcode:
Query1.ExecSQL ;
ausgeführt.

EDIT:
Noch ein Nachtrag... Habe jetzt ganz übersehen, dass das Ganze i2 mal passieren soll... Dann so
Delphi-Quellcode:
with Query1 do begin
   SQL.text := Format ('update TabellenName set lagerb = lagerb - %d * stueck',[i2]) ;
   ExecSQL ;
end ;

alzaimar 30. Nov 2005 22:59

Re: Daten Schleife schneller machen
 
Du musst aber supermuckl nicht so herablassend behandeln. Denn ob ein SQL-Befehl 'so toll' ist oder nicht, hängt in erster Linie von der Erfahrung und vom Wissen des Posters oder Lesers ab. Und nur weil Du vielleicht hier etwas mehr Wissen angehäuft hast, sollte kein Grund sein, von Oben herab so eine Äußerung durch den Kakao zu ziehen. In einem Punkt hat das supermuckl aber Recht: Die Fähigkeit, einen SQL-Befehl performant abzuarbeiten, ist in der Tat datenbankabhängig.

Wer wirklich Ahnung hat, hat es auch nicht nötig, das raushängen zu lassen. Denk mal drüber nach.

Jelly 30. Nov 2005 23:02

Re: Daten Schleife schneller machen
 
Zitat:

Zitat von alzaimar
Wer wirklich Ahnung hat, hat es auch nicht nötig, das raushängen zu lassen. Denk mal drüber nach.

Wie bist Du denn drauf. :gruebel:
Also ich hab doch hier keinen durch den Kakao gezogen. War zumindest nicht meine Absicht.

alzaimar 30. Nov 2005 23:14

Re: Daten Schleife schneller machen
 
Zitat:

Zitat von Jelly
Zitat:

Zitat von alzaimar
Wer wirklich Ahnung hat, hat es auch nicht nötig, das raushängen zu lassen. Denk mal drüber nach.

Wie bist Du denn drauf. :gruebel:
Also ich hab doch hier keinen durch den Kakao gezogen. War zumindest nicht meine Absicht.

Ist es zu spät für mich? Kann sein. Wenn Du dich nicht angesprochen fühlst, dann bin ich zu alt. Deine Äußerung 'so toll ist ...' lies mich annehmen, Du würdest das nicht Ernst nehmen, aber jetzt seh' ich erst, das Du es bist, Jelly. Stimmt. Ist nicht Deine Art.

Tschuljung.

Pluto 1. Dez 2005 00:29

Re: Daten Schleife schneller machen
 
Genereller Tipp:
Solche Schleifen können ganz schön Zeit kosten, insbesondere wenn die Datenbank
auf einem Server im (lokalem) Netz steht. (Es lässt sich auch nicht alles mit
SQL machen)

Ich gehe in solchen Fällen so vor:
1. Mit einer Query die Daten in ein Clientdataset laden.
2. Daten dann lokal verarbeiten. Da Alles im Memory abläuft, werden auch lange Schleifen
mit tausenden von Datensätzen blitzschnell verarbeitet.
3. Mit ApplyUpdates Resultate auf einen Rutsch in die Datenbank übertragen.

robby3 1. Dez 2005 19:54

Re: Daten Schleife schneller machen
 
Hei Danke es funzelt mit dem Code.
Delphi-Quellcode:
with Query1 do begin
   SQL.text := Format ('update TabellenName set lagerb = lagerb - %d * stueck',[i2]) ;
   ExecSQL ;
end ;
Nochmals Danke. :bounce2:

supermuckl 1. Dez 2005 20:01

Re: Daten Schleife schneller machen
 
das "so toll" hätte ich wohl noch ein wenig ironischer erscheinen lassen sollen ;)
ich bin schon etwas länger mit mysql + php + delphi am querys bauen.
aber kein problem, ich habs nicht persönlich genomen jelly :)
//edit
ich wollte halt nicht gleich die lösung auf dem silbertablett präsentieren.

Jelly 2. Dez 2005 01:40

Re: Daten Schleife schneller machen
 
Zitat:

Zitat von supermuckl
aber kein problem, ich habs nicht persönlich genomen jelly :)

Passt schon, wollt ja auch keinem was unterstellen. Hauptsache die Frage ist beantwortet.

alzaimar 2. Dez 2005 08:23

Re: Daten Schleife schneller machen
 
Zitat:

Zitat von Pluto
Es lässt sich auch nicht alles mit SQL machen...

Aber fast Alles. Man muss nur vom Denken in 'Records' Abstand nehmen und mit Mengen arbeiten. Während Access, Paradox etc. ISAM-Datenbanken sind (die also mit einzelnen Records arbeiten), sind moderne DBMS (mySQL 5, MSSQL, FB, Oracle etc.) mengenbasierte Datenbanken. Das bedeutet, das eine Tabelle als Ganzes betrachtet wird. Die Operationen (Select, update, delete etc.) sind darauf ausgelegt, immer mit der (Teil-)Tabelle als Ganzes zu arbeiten. Sie sind dann nicht wesentlich langsamer, als wenn man immer nur einen Record betrachtet.

1000xInsert ist viel viel langsamer als ein Insert, der 1000 Records auf einmal einfügt, etwa per
SQL-Code:
insert into Table (field1, field2) select myField1, myField2 from MyTable
Und ein Select, das 1000 Records liefert ist viel schneller (fast 1000x) als 1000 selects, die immer nur ein Record abholen.

Es gibt natürlich Fälle, wo man es mit einem einfachen Befehl nicht hinbekommt, dann nimmt man eine temporäre Tabelle. Und wenn es dann nicht geht, kann man immer noch über einen Cursor die zu modifizierende Tabelle durchiterieren (alles z.B. in einer Stored Procedure auf dem Server). Das geht i.A. schneller, als das von Pluto vorgeschlagene Verfahren: Was passiert?
in etwa das hier:
SQL-Code:
Select * from Tabelle
<Verarbeitung im Client>
<-bis hier ist die Welt noch in Ordnung>
Update Tabelle set .....
Update Tabelle set .....
<100000 mal das gleiche Spiel>...
Update Tabelle set .....
Die Verarbeitung im Client ist schneller (aber wirklich nur, wenn für jeden Record sehr komplexe operationen notwendig sind).
Die Übermittlung der Änderungen frisst extrem viel Zeit und belastet den Server und das Netz. Bei 100.000 Datensätzen mit Sicherheit der falsche Ansatz.

Ich persönlich kenne keinen Fall (bitte wörtlich nehmen), wo die clientseitige Verarbeitung (einen richtigen DB-Server vorausgesetzt) schneller ist als die serverseitige Verarbeitung. Diese hat aber einen *entscheidenden* Nachteil in einer Mehrbenutzerumgebung: Sie belastet den Server. Das ist der Grund, warum man die clientseitige Verarbeitung andenken sollte, wenn viele Leute mit der DB arbeiten, bzw. die Verwurstung einer Tabelle sehr oft vorkommt. Dann ist das aber i.A. schlechtes Design.

Verwurstungen sollte man über Trigger realisieren: Dann werden z.B. einzelne Spalten anderer Tabellen immer dann überarbeitet, wenn sich einzelne Einträge ändern. Beispiel: Rechnungen und Rechnungspositionen. Anstatt die Rechnungssumme immer komplett über alle Positionen zu berechnen, kann man auch einen Trigger schreiben, der bei Änderungen an der Tabelle 'Rechnungspositionen' aktiv wird:
Bei INSERT: Addiere den Preis der Rechnungsposition zur Gesamtsumme der Rechnung.
Bei DELETE: Subtrahiere den Preis der Rechnungsposition von der Gesamtsumme der Rechnung.
Bei UPDATE: Subtrahiere den alten Preis und addiere den neuen Preis.

Auf diese Weise hat man immer die korrekte Rechnungssumme (sofern dieses Felder für die direkte Änderung gesperrt sind) und muss nie rechnen. Man bekommt die Rechnungssummen *sofort*, ohne jegliche Zeitverzögerung. Der Preis hierfür ist eine um ein paar Mikrosekunden erhöhte Zeit beim Update der Rechnungspositionstabelle. Na und?


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