AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Viele Datensätze Updaten / vergelichen
Thema durchsuchen
Ansicht
Themen-Optionen

Viele Datensätze Updaten / vergelichen

Ein Thema von Dumpfbacke · begonnen am 15. Jul 2007 · letzter Beitrag vom 18. Jul 2007
Antwort Antwort
Seite 1 von 2  1 2      
Dumpfbacke

Registriert seit: 10. Mär 2005
Ort: Mitten in Deutschland
332 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Viele Datensätze Updaten / vergelichen

  Alt 15. Jul 2007, 16:36
Datenbank: Interbase • Version: V6.1 • Zugriff über: InterbaseExpress
Hallo leibe Delphianer,
ich muß hier etlich Datensätze vergeleiche bzw. aufbereiten updaten. Die Daten werden im CSV Format geliefert. Als erstes übertrage ich die Daten mal in eine Interbase Datei. Dieses Daten sollen nun umgewandelt bzw. mit Daten in eiener anderen Interbase DB verglichen werden. Es handelt sich um ca. 700.000 Datensätze.

Ich bekomme immer nach ca. 70.000 Datensätze eine Fehlermeldung, das zu wenige Arbeitsspeicher vorhanden ist und das auf einem Server mit 8 GB Ram.

Ich denke mal, das ich ein Fehler in meinen Programm habe welche ich einfach nicht finden kann. Ich habe mal den Code auf das nötigste gekürzt und hoffe, das mir hier jemand helfen kann. Es sein den Speicher nicht mehr freizugeben

Zuerst mal die Komponenten
SucheDaten1,SucheDaten,SucheDaten3,KanalSuchen sind TIBQuery´s
BearbeiteDaten1 ist eine TIBDataset

Ich habe hier schon einiges versucht wie z.B. ein Commit auf die Datenabk nach ca. 10.000 Datensätzen. Nur gebracht hat bis jetzt alles noch nicht.


Delphi-Quellcode:
procedure TPPusKanalEinlesen.DatenEinlesen;
var
I: Integer;
FehlerZaehler: integer;
Kanal: string;
HKanal1,HKanal2,HKanal3: string;
KanalZahl: integer;
Zaehler: integer;
begin
 Daten.SucheDaten1.Prepare;
 Daten.SucheDaten2.Prepare;
 Daten.SucheDaten3.Prepare;
 Daten.BearbeiteDaten1.Prepare;
 Daten.AnfangsDaten.Active := False;
 Daten.AnfangsDaten.Active := True;
 Daten.AnfangsDaten.First;
 While not Daten.AnfangsDaten.Eof do
     begin
     Daten.SucheDaten1.ParamByName('Wert1').AsSTring := Daten.AnfangsDaten.FieldByNAme('Wert1').AsString;
     Daten.SucheDaten1.Active := True;
     Daten.SucheDaten2.ParamByName('Wert2').AsSTring := Daten.AnfangsDaten.FieldByNAme('Wert2').AsString;
     Daten.SucheDaten2.Active := True;
     if (Daten.SucheDaten1.RecordCount > 0) and (Daten.SucheDaten2.RecordCount > 0 ) then
      begin
       Daten.BearbeiteDaten1.ParamByName('Test1').AsString := Daten.SucheDaten2.FieldByName('Test1').AsString;
       Daten.BearbeiteDaten1.ParamByName('Test2').AsString := Daten.SucheDaten1.FieldByName('Test2').AsString;
       Daten.BearbeiteDaten1.Active := True;
       if Daten.BearbeiteDaten1.RecordCount > 0 then
        begin
         //Wurde gefunden
         if Daten.BearbeiteDaten1.FieldByName('Kanal').AsString = 'then
          begin
           //Es ist bis jetzt noch kein Kanal angegeben.
           Daten.BearbeiteDaten1.Edit;
           //Hier wird noch etwas andres gemaucht habe ich jedoch gelöscht da unwichtig
           Daten.BearbeiteDaten1.FieldByName('TestDatum').AsString := DateToStr(AktuellesDatum);
           Daten.BearbeiteDaten1.Post;
          end
         else
          begin
           if Daten.BearbeiteDaten1.FieldByName('Kanal').AsString <> Kanal then
            begin
             Daten.BearbeiteDaten1.Edit;
             //Hier wird noch etwas andres gemaucht habe ich jedoch gelöscht da unwichtig
             Daten.BearbeiteDaten1.FieldByName('TestDatum').AsString := DateToStr(AktuellesDatum);
             Daten.BearbeiteDaten1.Post;
            end;
          end;
        end
       else
        begin
         FehlerZaehler := FehlerZaehler +1;
         Fehler.Caption := IntToStr(FehlerZaehler);
        end;
      end
     else
      begin
       FehlerZaehler := FehlerZaehler +1;
       Fehler.Caption := IntToStr(FehlerZaehler);
      end;
   Daten.AnfangsDaten.Next;
  end;
 Daten.TransEdit.Commit;
end;
Tanja
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: Viele Datensätze Updaten / vergelichen

  Alt 15. Jul 2007, 19:53
Hallo Tanja,

dein Hauptspeicherproblem kann ich nicht entdecken, aber die Performanz sollte so nicht sehr berauschend sein. Du solltest prüfen, warum du neben IBDataSet noch IBQuery verwendest, eine Komponente die eher als Migrationshilfe für BDE-Anwendungen konzipiert ist. Das Commit sieht irgendwie unmotiviert aus, so ganz ohne StartTransaction.

Ich vermute, dass sich ein Großteil der Aufgaben durch eine Implementierung in SQL Procedure Language erledigen lässt - ohne Speicher- und Performanzprobleme - zumal du die Daten ja bereits in die Datenbank geladen hast.

Wenn du weitermachen willst wie bisher, dann solltest du vielleicht ein paar Prüfpunkte in deinen Code aufnehmen. Auf diese Weise kannst du herausfinden, wie sich der Speicherverbrauch zwischen signifikanten Code-Blöcken entwickelt und ob er in Schleifen ansteigt. Oder ist das Laden der CSV-Daten über StringList erfolgt und due hast diese Listen nicht freigegeben?

Grüße vom marabu
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

Re: Viele Datensätze Updaten / vergelichen

  Alt 15. Jul 2007, 20:17
Ich vermute das der hohe Speicherverbrauch an dern impliziten Tranaktionssteuerung der Komponenten liegt.
Markus Kinzler
  Mit Zitat antworten Zitat
Dumpfbacke

Registriert seit: 10. Mär 2005
Ort: Mitten in Deutschland
332 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Viele Datensätze Updaten / vergelichen

  Alt 15. Jul 2007, 20:23
Zitat von marabu:
Hallo Tanja,

dein Hauptspeicherproblem kann ich nicht entdecken, aber die Performanz sollte so nicht sehr berauschend sein. Du solltest prüfen, warum du neben IBDataSet noch IBQuery verwendest, eine Komponente die eher als Migrationshilfe für BDE-Anwendungen konzipiert ist. Das Commit sieht irgendwie unmotiviert aus, so ganz ohne StartTransaction.

Ich vermute, dass sich ein Großteil der Aufgaben durch eine Implementierung in SQL Procedure Language erledigen lässt - ohne Speicher- und Performanzprobleme - zumal du die Daten ja bereits in die Datenbank geladen hast.

Wenn du weitermachen willst wie bisher, dann solltest du vielleicht ein paar Prüfpunkte in deinen Code aufnehmen. Auf diese Weise kannst du herausfinden, wie sich der Speicherverbrauch zwischen signifikanten Code-Blöcken entwickelt und ob er in Schleifen ansteigt. Oder ist das Laden der CSV-Daten über StringList erfolgt und due hast diese Listen nicht freigegeben?

Grüße vom marabu
Hallo Marabu,
ich kann es auch nicht verstehen wo das Problem mit dem Speicher sein soll. Aus Verzweiflung habe ich nun bei jedem Post ein Commit gemacht. Danze ist nun noch langsamer, aber wegen mir kann es eine Tag bei der ersten Version laufen hauptsage es geht. Leider geht das auch nicht.

IBQuery habe ich benutzt um ID´s aus zwei verschieden Tabellen zu bekommen und herrauszufinden, wenn eine Datsatz nicht vorhanden ist, in welcher der zwei Tabellen es fehlt. In der Dritten Tabelle sind die nur die ID´s der beiden Tabellen vorhanden.

An eine Stored prodedure habe ich auch schon mal gedacht, jedoch wird es vermutlich nicht gehen. In einen Feld steht ein Sting, welches ich "zerlegen" muß und je nachden was dort drin steht eine Zahl einfügen. Dazu habe ich die Funktionen Pos,copy und Case of von Delphi benutzt.

An die Prüfpunkte habe ich auch schon mal gedacht, jedoch ob mich das weiterbingt weiß ich auch nicht. Das Problem ist ja bei diesem Code dauert es etlich Zeit, bis es 70.000 Datensätze verarbeitet hat und der Fehler kommt. Das Programm besteht nur aus dieser Schleife.

Die CSV Datei habe ich mittels Databump übertragen. Das war auch das einzige was funktioniert hat.

Ich beschreibe Dir mal den Aufbau des Files und der Tabellen

File:
Feld1,Fled2,Fled3

Mittels des Feld1 wird eine ID aus der ersten Tabelle geholt
Mittels des Feld2 wird eine ID aus der zweiten Tabelle geholt

In der dritten Tabelle steht nur die ID von Fled1 und Feld2 drin. Des weitern Gibt es ein Feld in den ich einen Zahl eintragen möchte und ein Feld in welches in das aktuelles Datum eintragen möchte. Die zahl muß wie oben beschrieben noch berechnet werden.

Hast du so etwas schon mal mit einer Stored Procedure erledigt ? Wie lange würde es bei einer Stored Prodeure denn Dauern bei ca. 750.000 Datensätze ?

Tanja
Tanja
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#5

Re: Viele Datensätze Updaten / vergelichen

  Alt 16. Jul 2007, 12:24
Hallo Tanja,

der Grundstein einer guten Lösung ist eine exakte Problembeschreibung - jedenfalls kann die Qualität der Lösung nicht besser sein als die Qualität der Analyse. Oft ist ein deklarativer Ansatz besser als ein prozeduraler, ganz besonders wenn SQL im Spiel ist.

In deinen Beiträgen erkenne ich die Tabelle Anfangsdaten A (Wert1, Wert2, ...), zwei Tabellen mit Suchdaten S1 (Test1, Wert1, ...) und S2 (Test2, Wert2, ...), sowie die Tabelle Bearbeitungsdaten B (Test1, Test2, Kanal, TestDatum, ...).

Du hast offensichtlich eine ein-eindeutige Schlüsselabbildung von A.Wert1 nach B.Test1 über S1, wodurch S1.Wert1 neben dem primary key S1.Test1 zum candidate key avanciert. Analoges gilt für S2. Andernfalls könntest du nicht wie gezeigt suchen.

Für jedes Tupel (A.Wert1, A.Wert2) suchst du ein korrespondierendes Tupel (B.Test1, B.Test2) um bei dessen Existenz einige Felder (B.TestDatum) in Abhängigkeit einer Funktion K(B.Kanal, ...) zu verändern. Die Funktion K() hast du nicht genau beschrieben. Wenn es sich dabei nur um verkettete String-Funktionen handelt, dann ist eine Implementierung in SQL sehr wahrscheinlich möglich. In meinem Beispiel habe ich K() als Null-Test eingesetzt:

SQL-Code:
UPDATE B
SET TestDatum = '2007-07-16'
WHERE Kanal IS NULL
AND EXISTS (
    SELECT B.*
    FROM A, B, S1, S2
    WHERE A.Wert1 = S1.Wert1
    AND A.Wert2 = S2.Wert2
    AND S1.Test1 = B.Test1
    AND S2.Test2 = B.Test2
)
Reverse Engineering ist nicht einfach. Wenn ich deine Anforderungen nicht richtig erkannt habe, dann kannst du sie gerne etwas präzisieren.

Freundliche Grüße
  Mit Zitat antworten Zitat
hoika

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

Re: Viele Datensätze Updaten / vergelichen

  Alt 16. Jul 2007, 12:32
Hallo,

mir fällt noch ein:

- RecordCount ersetzen durch Select Count(*)
(mit sqlmonitor mal prüfen)
- alles auf Unidirectional=true setzen
- mal die Speicherbelegung im Taskmanager verfolgen
- try finally bei Active=True
ich sehe nirgendwo ein Active False ?
- memcheck nehmen und mal nur 1000 Einträge nehmen


Heiko
Heiko
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#7

Re: Viele Datensätze Updaten / vergelichen

  Alt 16. Jul 2007, 12:41
Hallo Heiko,

bei einem Existenztest würde ich DataSet.IsEmpty prüfen - die Umstellung auf eine Zählung macht für mich nur Sinn, wenn eine großes Resultset zu befürchten wäre.

Wenn Tanja bei ihrem prozeduralen Code bleiben möchte, dann sind auch noch ein paar andere Dinge zu reparieren. Zum Beispiel wird der FehlerZaehler nie initialisiert. Ich kann mir aber nicht vorstellen, dass diese Lösung in Produktion gehen wird: 700.000 Aufrufe für Query.Open (Close fehlt im gezeigten Code) dürften den Job zu einem echten Langläufer machen. Vor allem wenn keine passenden Indexe eingerichtet wurden.

Freundliche Grüße
  Mit Zitat antworten Zitat
hoika

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

Re: Viele Datensätze Updaten / vergelichen

  Alt 16. Jul 2007, 15:43
Korrekt,

deshalb wird jede meiner Queries durch den ibplanalyzer geschickt.

Tanja:
Warum packst du die 750000 CSV-Dateien nicht schon
"ent-csv"'1 in eine Hilfstabelle,
mache noch ne id als autoinc (trigger) rein,
dann kannst du schnell mal mit "kleiner Tabelle" testen.

Die SP muss sich dann nicht mit String-Operationen rumärgern.

Ich würde auch erst mal rausfinden,
ob das Programm (memcheck) oder Interbase (task-manager) den Fehler bringen.


Heiko
Heiko
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

Re: Viele Datensätze Updaten / vergelichen

  Alt 16. Jul 2007, 15:46
Man könnte auch versuchen die CSV als external file einzubinden. Dadurch kann man diese wie eine Tabelle verwenden.
Markus Kinzler
  Mit Zitat antworten Zitat
hoika

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

Re: Viele Datensätze Updaten / vergelichen

  Alt 16. Jul 2007, 16:33
Durch die die könnte man die Dateien schneller leeren,
ginge natürlich auch, wenn man vor dem Import
mal "ein paar" Zeile der csb löscht...


Heiko
Heiko
  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 05:03 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