AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Große Datenmengen richtig verarbeiten bzw. Out of Memory
Thema durchsuchen
Ansicht
Themen-Optionen

Große Datenmengen richtig verarbeiten bzw. Out of Memory

Ein Thema von Monday · begonnen am 10. Jul 2018 · letzter Beitrag vom 4. Aug 2018
Antwort Antwort
Seite 1 von 2  1 2      
Monday

Registriert seit: 24. Aug 2012
103 Beiträge
 
FreePascal / Lazarus
 
#1

Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 10. Jul 2018, 06:27
Datenbank: SQLite • Version: 3 • Zugriff über: ZEOS
Hallo,

ich habe eine große Datenbank ( > 1 Mil. Datensätze ) und möchte die einzelnen Datensätze einzeln weiterverarbeiten.
Bei kleineren Datenmenge habe ich mir nie Gedanken über select & co gemacht. Bei größeren Datenmenge bekomme ich regelmäßig "Out of Memory" Probleme (Nicht zuletzt wegen geringen Arbeitsspeicher (4 GB)). Einzige Möglichkeit sehe ich, die Datensätze nur Häppchenweiße einzulesen. Schön finde ich das allerdings nicht, wie ich finde.

Gibt es noch effektivere Möglichkeiten als diese hier? Hier mein Grundgerüst:

Delphi-Quellcode:

var
temp , stop, a: integer;

begin
// temp ist der "eigene Datensatz Zähler"
//temp := 0; //Anfang der ID's

      Form1.ZQuery3.Close;
      Form1.ZQuery3.SQL.Clear;
      Form1.ZQuery3.SQL.Text := 'select min(id) as mm from tabelle1;';
      Form1.ZQuery3.Open;
      temp := StrToInt(Form1.ZQuery3.FieldByName('mm').AsString);



 while stop = 0 do begin //Datensätze nur abschnittsweise laden
   Form1.ZQuery1.Close;
   Form1.ZQuery1.SQL.Clear;
   Form1.ZQuery1.SQL.Text := 'select id,* from tabelle1 where id >= "'+IntToStr(temp)+'" Limit 100;'; // Limit 100: Ggf. verkleinern
   Form1.ZQuery1.Open;

   Form1.ZQuery3.Close;
   Form1.ZQuery3.SQL.Clear;
   Form1.ZQuery3.SQL.Text := 'select max(id) as mm from tabelle1';
   Form1.ZQuery3.Open;
   if (((StrToInt(Form1.ZQuery3.FieldByName('mm').AsString)-2)) <= temp) then begin stop :=1; exit; end; // Wenn Ende erreicht von DB, dann Schleife beenden


  for a := 0 to ZQuery1.RecordCount-1 do begin
  // *** Hier die einzelnen Datensätze verarbeiten ***
  end; //for


 end; //while



end;
Liebe Grüße
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.879 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 10. Jul 2018, 07:13
In diesem Code liegt viel im Argen.

Warum die Verweise auf eine Instanz eiesn Formulars (Form1). Wo steht dieser Code in Form1 oder in einem anderen Formular?

Was für einen Typ hat das Feld ID? Warum fragst Du es als String ab und wandelst es dann in einen Integer?
Warum fragst Du nicht am Anfang ab, was das Maximum ist sondern bei jedem Schritt?
Welches DBMS?
Warum keine parametrisierte Abfrage?
Markus Kinzler

Geändert von mkinzler (10. Jul 2018 um 08:03 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.277 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 10. Jul 2018, 08:11
Hallo,

Delphi-Quellcode:
for a := 0 to ZQuery1.RecordCount-1 do begin
  // *** Hier die einzelnen Datensätze verarbeiten ***
  end; //for
select id,*
Brauchst Du wirklich alle Felder der Tabelle?

Das könnte schon das Problem sein.
Hier werden ja nach DB alle Datensätze lokal heruntergeladen und zwischengespeichert.
Ändere das mal ab.

Delphi-Quellcode:
ZQuery1.UniDirectional:= True;
while not ZQuery1.Eof do
begin
  // Datensatz verarbeiten

  ZQuery1.Next;
end;
Heiko
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#4

AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 10. Jul 2018, 08:23
Die Frage wäre auch, was die Verarbeitung macht?
z.B.
- Selektierte Daten ändern
- neue erzeugen / ggF. in andere Tabelle
- irgendwas zählen
?

Viele solcher Maßnahmen können durch SQL erledigt werden, ohne dass man überhaupt Daten aus der DB lokal holt.

Ist es nichts von dem oben, sondern -sagen wir mal- ein kleiner Datenabgleich und speichern eines Resultats in einer Datei, könnte man den Datenzugriff schlanker gestalten, Stichwort unidirektionale Cursor, Readonly, etc..
Ich weiß allerdings nicht, was die sqlite clients da können.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.401 Beiträge
 
Delphi 12 Athens
 
#5

AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 10. Jul 2018, 09:55
Ich hoffe SQLite kann das und ZEROS sollte auch eine Fetch-Funktion bieten,
also wo das DataSet nicht alle Daten runterläd, sondern nur ein Fenster/Teil des ganzen ResultSets.

http://zeoslib.sourceforge.net/viewtopic.php?t=20005
http://forum.lazarus.freepascal.org/...?topic=13192.0

Wenn nicht, dann mußt du das eben selber implementieren, die Abfrage mehrmals mit LIMIT/OFFSET ausführen und die Daten stückchenweise holen.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.010 Beiträge
 
Delphi 2009 Professional
 
#6

AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 11. Jul 2018, 08:09

Delphi-Quellcode:
ZQuery1.UniDirectional:= True;
while not ZQuery1.Eof do
begin
  // Datensatz verarbeiten

  ZQuery1.Next;
end;
Das Setzen von UniDirectional auf True muss vor dem Öffnen (ZQuery1.Open) der Abfrage erfolgen, danach ist es "zu spät", wenn ich mich nicht irre?
Michael Justin
  Mit Zitat antworten Zitat
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
274 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 11. Jul 2018, 10:19
Davon gehe ich aus.
[Delphi 11.3.1 Enterprise; Win10/11; MySQL; VCL]
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.224 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 11. Jul 2018, 10:40
Davon gehe ich aus.
Würde ich nicht.
Bei SQLite läuft die DB im eigenen Adressraum (Embedded).
Das was bei einer richtigen SQL-Datenbank mit eigenen Prozess gut/positiv ist, kann für eine Embedded-DB den gegenteiligen Effekt bewirken.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
MichaelT

Registriert seit: 14. Sep 2005
Ort: 4020 Linz
561 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 13. Jul 2018, 08:48
Diese Unart alles zu holen kam mit Access auf resp. hat Access den Trend verstärkt * zu nehmen anstatt konkrete Datenmengen zu definieren.

In weiter Folge wird kein Wert mehr darauf gelegt ob ein Join Kriterium ein Integer ist usw...

Peu a peu wird's langsam.

Access ware eine der ersten DBs die den Spaltentyp aufgrund der Analyse von ein paar Datensätzen hat geraten.




select id,*
Brauchst Du wirklich alle Felder der Tabelle?

Das könnte schon das [/DELPHI]
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#10

AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory

  Alt 10. Jul 2018, 08:21
Wenn zu viele Daten von der DB zurück geliefert werden, warum arbeitest Du dann mit
'select id,* from tabelle1 where id ... Zumindest das Feld ID ist dann doppelt.

Wenn Du schon ID zu irgendwelchen Berechnungen und Vergleichen benutzt (-2,<=), dann solltest Du wenigstens eine auf- oder absteigende Reihenfolge sicherstellen
order by id asc/desc Über einen Integer der als Boolean mißbraucht wird, möchte ich mich nicht weiter auslassen.

Und wenn Du min(ID) bzw. max(ID) benötigst, dann kannst Du das zu Anfang Deiner Verarbeitung abfragen, und mußt nicht die ganze Zeit eine Connection offen halten.

Gruß
K-H

Edith:
nach dem Abholen der Datensätze muß der .RecordCount nicht zwangsläufig korrekt sein.
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector

Geändert von p80286 (10. Jul 2018 um 08:24 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:35 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