AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory
Zitat:
Gruß K-H |
AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory
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. Zitat:
|
AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory
In Ergänzung: Es bietet sich in solchen Fällen über Arrays im Mittel ganz performant auf Datenmengen zugreift.
Wir haben die Arraysize bis zu einem Limit bei jedem Fetch verdoppelt bis das Limit hinter dem keine Geschwindigkeitszugewinn mehr zu holen war. Zumindest auf Oracle und SQL Server hat die 'Strategie' sehr gute Ergebnisse geliefert egal wieviele Sätze in den Tabellen gespeichert waren. Zitat:
|
AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory
Zitat:
Wenn man mal bei DB-Zugriffen "ungewöhnliches" Verhalten seitens seines Delphiprogrammes beobachtet: Es kann sehr hilfreich sein, sich die Datenbankverbindung und die Treiber anzuschauen / anzupassen, statt im Programmquelltext mehr oder weniger verzweifelt nach Workarounds um festgestellte Probleme zu suchen. Früher (zu BDE-Zeiten) konnte es durchaus hilfreich sein, beim Zugriff auf Oracle auch deren Treiber zu nehmen und nicht den von Microsoft, der (damals?) auf den Systemen schon vorhanden war. Keine Ahnung, wie sich das bis heute so entwickelt hat, aber die Fehlermöglichkeiten zwischen eigenem Programm und Datenbank sollte man nie ausklammern. @MichaelT select * from ist eine Unsitte, die verboten gehört. Es wird nur das selektiert, was man auch benötigt -> kleinstmögliche Ergebnismenge, sowohl in Bezug auf die ausgewählten Spalten als auch auf die ausgewählten Zeilen. Alles zu holen und dann im Programm nur das benötigte zu verarbeiten ist einfach nur schlecht. |
AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory
Zitat:
Unsitte, nicht unbedingt Alles zu holen ist tatsächlich schlecht. Wenn hinter dem from eine definierte Datenquelle hängt (view), die Spalten und Zeilen wie gewünscht eingrenzt, finde ich es nicht problematisch. Spaß macht es, wenn man die Datenquelle ändert und "Select *" in der Anwendung einfach die zusätzlichen (oder weniger) Daten liefert. Dazu gehört allerdings eine eigene Feldverwaltung. |
AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory
Zitat:
Delphi-Quellcode:
könnte schon scheitern, weil die hier ursprunglich erwartete Spalte eventuell eine andere Position bekommen hat und wir hier den Inhalt einer Zeichenkette bekommen und nicht den in Spalte 1 erwarteten Integer.
i := qry.fields[1].AsInteger
Und wenn man statt * die benötigten Spalten angibt, schreibt man zwar mehr, aber wenn davon eine Spalte "verlustig" gehen sollte, knallt das SQL, die Query beim Open, und nicht erst ein eventuell viel später erfolgender Zugriff auf die "verschwundene" Spalte. Mag es halt, wenn Fehler möglichst nah an der Fehlerursache auftreten und wenn eine mögliche Fehlerursache im SQL liegen kann, dann möchte ich, dass das SQL mir "um die Ohren fliegt" und nicht erst die Verarbeitung der erhaltenen, aber nicht so erwarteten, Ergebnismenge. |
AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory
Erstmal vielen Dank für eure Antworten.
Ich habe gerade gesehen, dass mir bei dem Beitrag ein Fehler unterlaufen ist. Ausgerechnet die wichtigste Zeile fehlt: temp := temp+100; Dieser kommt am Schluss. Ich habe unten nochmal den überarbeiteten code angefügt. "Form1." kann man selbstverständlich rausmachen. "select id,*" - das * war nur zu anschauung. Ich würde auch nur die Felder wählen, die ich wirklich benötige. Das mit der Fetch Funktion habe ich versucht. Entweder habe ich nicht verstanden wie es richtig geht, oder es geht nicht. Die Funktion wäre schon nice gewesen. Dann könnte ich mir den unteren code sparen; Weil dieser soll ja die Datensätze abschnittsweise einlesen. Aber ich denke, es lohnt sich, mich damit mal ausführlich auseinanderzusetzen. Das mit .RecordCount habe ich rausgenommen. Ich dachte mit RecordCount wird die maximaldatensätzeanzahl angezeigt. Mit .RecNo wird die aktuelle Datensatz Nr angezeigt? Hier der neue Code:
Delphi-Quellcode:
var
temp , stop, stopz, a: integer; begin // temp ist der "eigene Datensatz Zähler" //temp := 0; //Anfang der ID's stop := 0; ZQuery3.Close; ZQuery3.SQL.Clear; ZQuery3.SQL.Text := 'select min(id) as mm from tabelle1;'; ZQuery3.Open; temp := StrToInt(ZQuery3.FieldByName('mm').AsString); ZQuery3.Close; ZQuery3.SQL.Clear; ZQuery3.SQL.Text := 'select max(id) as mm from tabelle1'; ZQuery3.Open; stopz := ((StrToInt(ZQuery3.FieldByName('mm').AsString)-2)); while stop = 0 do begin //Datensätze nur abschnittsweise laden ZQuery1.Close; ZQuery1.SQL.Clear; ZQuery1.SQL.Text := 'select id,* from tabelle1 where id >= "'+IntToStr(temp)+'" Limit 100;'; // Limit 100: Ggf. verkleinern ZQuery1.Open; if (stopz <= temp) then begin stop :=1; exit; end; // Wenn Ende erreicht von DB, dann Schleife beenden for a := 0 to stopz do begin // *** Hier die einzelnen Datensätze verarbeiten *** end; //for temp := temp+100; // muss gleich sein wie bei Limit oben end; //while end; |
AW: Große Datenmengen richtig verarbeiten bzw. Out of Memory
Delphi-Quellcode:
Die Syntax mußt Du noch prüfen da ich ZEOS nicht so genau kenne.
var
firstid : integer; // ggf cardinal oder int64 alldone : boolean; begin alldone:=false; firstid:=0; // Annahme die IDs sind alle größer als 0 ZQuery1.Close; ZQuery1.SQL.Text := 'select id chkid,* from tabelle1 where id >= :minid order by id Limit 100;'; repeat Zquery.Parameters.ParambyName('minid').asinteger:=firstid; ZQuery1.Open; zQuery1.First; if not zquery1.EOF then begin repeat firstid:=Zquery1.Fieldbyname('chkid').asinteger; //mach was mit dem Datensatz Zquery1.next; until Zquery1.EOF; end else begin // alle Datensätze sind verarbeitet alldone:=true; end; ZQuery1.close; inc(firstid); until alldone; end; Aber damit solltest Du das erreichen was Du willst. Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:11 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