![]() |
Datenbank: MySQL • Version: 5.5.28 • Zugriff über: Devart DBExpress
Abfrage von großen Datenmengen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Zusammen,
sobald ich eine Abfrage starte, welche mehr als ca. 20 000 Datensätze zurückliefert läuft mein Arbeitsspeicher voll und die Exception "Nicht genügend Speicher für diese Operation" wird ausgegeben. Des Weiteren habe ich noch eine Master/Detail-Beziehung Der Master (Mandant) hat 8 Datensätze, je nach Master gibt es unterschiedliche Buchungen(Detail).
Code:
Sobald ich die innerhalb des Masters scrolle, ändert sich ja auch der Details (was gewünscht ist), doch bei einer größeren Anzahl kommt die obengenannte exeception.
+-----------+-------------------+
| Mandant | Anzahl Buchungen | +-----------+-------------------+ |!01 | 11000 | |!02 | 30000 | |!03 | 40000 | |!04 | 523624 | |!05 | 10000 | |!06 | 10000 | |!5 | 10000 | +-----------+-------------------+ Hat jemand eventuell eine Idee wie das Problem gelöst werden kann. Viele Grüße und vielen Dank im Voraus Christian P.S.: Das Projekt sowie ein Backup der MySQL-Daten sind angehängt |
AW: Abfrage von großen Datenmengen
20.000 Datensätze. Hier die Frage wieder: Wer schaut sich dies direkt an?
Mit welchen Compilereinstellungen ist die Anwendung erstellt? Mit maximalen Debug-Infos? |
AW: Abfrage von großen Datenmengen
Also 20.000 Datensätze ist noch das kleinste, aber wer des anschauen will keine Ahnung. Ist glaub für ein komplettes Geschäftsjahr.
Ja die Anwendung wurde mit den maximalen Debug-Infos kompiliert. Auch den Debug-DCUs. Muss ich es irgendwie anders kompilieren? Viele Grüße Christian |
AW: Abfrage von großen Datenmengen
zum einen, wäre es nicht sinnvoller gleich eine Datei als Ausgabe zu generieren? (Excel)
Ohne Debug-Info ist die Exe etwas kleiner und man etwas mehr Platz. Ggf. wäre es sinnvoll einen readonly-cursor zu verwenden (falls definierbar) oder den Cursor auf dem Server zu verwenden (falls es geht) Gruß K-H |
AW: Abfrage von großen Datenmengen
Verwendest Du ClientDataSets?
Dann werden alle Abfragedaten darin (im Speicher) verwaltet. Insofern eignet sich DBExpress nicht unbedingt für solche größeren Rückgabemengen von Abfragen. (soweit meine Einschätzung als DB-Laie) |
AW: Abfrage von großen Datenmengen
Jein. Ich nutze zwei TSimpleDataSet und eine TSQLConnection mit dem Devart Treiber MySQL Direct. Das TSimpleDataSet erbt ja vom TCustomClientDataSet.
Gibt es keine Komponenten für Read-Only zugriffe, da ich die Daten NUR lesen will und nicht wieder wo anderes hin speichere oder manupuliere möchte. Zitat:
Grüße |
AW: Abfrage von großen Datenmengen
Zitat:
Gruß K-H |
AW: Abfrage von großen Datenmengen
Wenn du als Query eine TSQLQuery meinst, dann nicht.
Sorry dass ich gerade nicht verstehe was du meinst. :) |
AW: Abfrage von großen Datenmengen
Ich wollte mir dein Projekt mal ansehen, aber ich glaube dein MySQL Backup ist nicht vollständig, kann das sein?
In der Datei stehen nur zwei Tabellen: Buchungen und email Im Quellcode verweist du aber auf die Tabelle Mandant?! |
AW: Abfrage von großen Datenmengen
Zitat:
|
AW: Abfrage von großen Datenmengen
Liste der Anhänge anzeigen (Anzahl: 1)
Sorry habe mich beim Backup vertan. Daher im Anhang nun das Backup der Tabelle "Mandant".
Man beachte es nur Test-Daten die ich mir erzeugt habe. Daher steht nichts sinnvollen in den Datensätzen |
AW: Abfrage von großen Datenmengen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Leider waren es nur ca. 30MB, was reduziert wurde. Aber bei 1,7 GB ist das nur ein Tropfen auf den heißen Stein. Grüße |
AW: Abfrage von großen Datenmengen
Schon mal andere MySQL-Version probiert?
Hatte schon den Fall das eine MySQL-Version verpfuscht war und falsche infos zurück geliefert hatte so das auf Clientseite einiges Falsch gelaufen ist Hast du blob-Felder? Bei Oracle war/ist es so das diese (auch ohne Inhalt) im Instant-Client mit sehr viel "luft" (Speichertechnisch) auf Clientseite verwaltet werden. Verwendest du libmysql.dll oder den direkten Modus der Komponenten? Probier mal den jeweilig anderen Modus aus. |
AW: Abfrage von großen Datenmengen
Also ich kann das Problem hier jetzt nachvollziehen... Spontan würde ich sagen es liegt an den (komischen) dbExpress-Zugriffskomponenten...
Habt ihr die schon gekauft, oder seid ihr noch am testen? Ich rate dir, die Zugriffskomponenten zu wechseln und auf TQuery zu setzen. ![]() Kostet ja im Prinzip in der kleinsten Ausbaustufe genau so viel. Damit wirst du wohl viel weniger Probleme haben... |
AW: Abfrage von großen Datenmengen
Zitat:
Das Simple-/ClientDataSet lädt stndardmäßig das komplette Abfrageergebnis in den Hauptspeicher und da knallt es natürlich ab einer gewissen Menge. Du kannst also entweder deine Abfrage mit einer sinnvollen WHERE-Klausel verkleinern, was aber ohne Kenntnis möglicher Kriterien schwierig wird, oder (besser) du verzichtest auf das Grid und verwendest lediglich ein TSQLDataSet (das ist unidirektional und somit nicht in einem Grid darstellbar). Da sich aber wohl kaum jemand die ganzen 20000 Datensätze in dem Grid anschauen will, sollte das zu verschmerzen sein. Wenn es nicht ohne das Grid geht, musst du feststellen, nach welchen Kriterien die Abfrage eingeschränkt werden kann (z.B. Jahr/Monat der Buchungen oder so). Dann zuerst das Kriterium eingeben und dann erst die Abfrage öffnen. Vergiss alles bezüglich der Debug-Infos, das Problem ist die Menge der abgefragten Daten. |
AW: Abfrage von großen Datenmengen
Zitat:
Gruß K-H |
AW: Abfrage von großen Datenmengen
Ihm geht dabei aber dann doch die Master / Detail Navigation flöten, oder?
Das Problem hätte er wie gesagt mit den gleichteuren MyDAC-Komponenten von DevArt nicht... |
AW: Abfrage von großen Datenmengen
(Bezugnahme auf Uwe´s Beitrag)
... oder eine Alternative zum DBExpress wählen. Ich kenne mich im Detail zwar nicht aus und WILL NICHT die BDE empfehlen, aber unter BDE wurden nur die Datensätze in das DBGrid geholt, die auch dargestellt wurden. Ich weiß nicht, welche Möglichkeiten sich da aktuell anbieten. Bei DBExpress zu bleiben ist m.E. vor allem sinnvoll, wenn man eine spätere Skalierung auf DataSnap für möglich hält. So ließe sich das Projekt (m.E.) am einfachsten auf DataSnap umstellen. Ist das ausgeschlossen und sind große bidirektionale Datenmengen im Spiel ist BDExpress möglichweise nicht erste Wahl. (meine aktuelle Einschätzung) |
AW: Abfrage von großen Datenmengen
Zitat:
Zitat:
|
AW: Abfrage von großen Datenmengen
Zitat:
|
AW: Abfrage von großen Datenmengen
Ich kann mir das Projekt gerade nicht ansehen, aber vielleicht gibt es ein Memoryleak o.ä. (dass z.B. dynamisch immer neue Verbindungen hinzugefügt werden oder so)?
EDIT @Christian: Bist Du auf MySQL festgelegt? Sonst teste doch mal Firebird... |
AW: Abfrage von großen Datenmengen
Diese redundaten (Adress-) Daten in der Buchungen Tabelle sind ja nun auch nicht wirklich hilfreich und haben in der Tabelle "buchungen" eigentlich nichts verloren.
Die Adressinformationen gehören in eine Belegtabelle und die Referenz auf den Beleg gehört in die Buchungstabelle. Ich würde hier einfach mal ordentlich normalisieren und dann wieder zu diesem Problem zurückkommen - wahrscheinlich hat sich dieses Problem dann schon erledigt. Alle Spalten als varchar(500) ist auch nicht gerade kreativ ... |
AW: Abfrage von großen Datenmengen
da kommt mir doch ein Gedanke wegen der Größe ...
73 Felder mit VARCHAR(500) Wenn die Datenbankkomponente jetzt die Felder in maximaler Größe und als Unicode in den Speicher holt dann sind das bei 20000 Zeilen:
Code:
73 {Felder} * 500 {CHAR} * 2 {Unicode} * 20000 {Zeilen} = 1460000000 Bytes
1,360GB |
AW: Abfrage von großen Datenmengen
Zitat:
Zitat:
Zitat:
|
AW: Abfrage von großen Datenmengen
Zitat:
Seine Testdaten zeigen aber keine annähernde füllung dieser jeweils 500 Byte (Backup ist insgesamt ca. 500 MB groß) so das ich denke das diese 20.000 Datensätze kein 1,5 GB (wenn keine Fehler vorhanden sind) füllen würden. |
AW: Abfrage von großen Datenmengen
Es soll ja auch schon vorgekommen sein das varchar500 als 500 Blanks über die Leitung gehen, intern aber wirklich nur ein Blank groß sind.
Vielleicht hilft da der Debugger weiter? Gruß K-H |
AW: Abfrage von großen Datenmengen
Es kann natürlich sein, dass die Datenbank (File) leere Einträge packt, der Treiber die DataSet-VarChar-Felder aber immer mit Leerzeichen auffüllt bzw. einfach maximal viel Speicherplatz reserviert.
|
AW: Abfrage von großen Datenmengen
Zitat:
Der eigentliche Fehler in der Produktivanwendung war auf Oracle, da sind des sogar 250 000 Datensätze. Zitat:
Ich hoffe, man möge es mir verzeihen. Zitat:
Gibt es bei einer TSQLQuery die Möglichkeit eine Master-Detail-Beziehung aufzubauen (Kann es leider nicht nachprüfen, da ich nur im Unternehmen eine Delphi-Version habe)? Das mit dem Debugger werde ich gleich mal morgen ausprobieren. Viele Grüße |
AW: Abfrage von großen Datenmengen
Zitat:
vielleicht solltest Du mal ganz von Anfang an erzählen, um was es geht. Mir scheint hier wird nur an den Symptomen herum gemacht. (nicht pers. gemeint) Gruß K-H |
AW: Abfrage von großen Datenmengen
Ist OK. Also es war einmal .... ne nur Spaß.
Es gibt zwei Anwendungen. Die Eine, ein ERP-System (Java), bereitet Daten für ein Report-Template auf. Anschließend wird die zweite Anwendung gestartet. Diese Anwendung ladet die Daten und erstellt ein PDF aus den Daten mit Hilfe des Templates. Aktuelle gibt es ca. 90 verschiedene Templates mit ca. 40 verschiedenen SQL-Abfragen. Von diesen Abfragen werden je nach Template 2-3 Abfragen benötigt. Ja, manche Templates haben das selbe Abfrage. Da das Laden der SQL-Abfrage und das Zusammenbauen der Master-Detail-Beziehungen dynamisch geschieht, sollte es halt eine einheitliche Lösung sein. Nun zum Problem: Aktuell soll ein Report generiert werden, welcher im Detail ca. 250 000 Datensätze besitzt. Hierbei kommt es zur der Exception, dass nicht genügend Speicher vorhanden ist, also die Exception auf dem dieser Thread basiert. Die Datenbank an dem der Fehler auftrat war Oracle. Da ich den Fehler "schnell" reproduzieren wollte, habe ich kurzer Hand ein paar Testdaten geniert. Dadurch auch die Problematik mit Felder VARCHAR(500). Sollte quick'n'dirty sein. Die Anzahl der Spalten im Produktivsystem liegen so bei 50 Stück mit unterschiedlichen Datentyp. Da ich den Reportbuilder von Digital Methaphors verwende benötige ich ein Dataset (siehe ![]() Vielleicht gibt es auch eine andere Lösung, solange es meine Master-Detail-Beziehung nicht gefährdet. Hoffe ich habe alles erklärt und auch verständliche erklärt. Falls noch einige Einzelheiten fehlen werde ich diese gerne nachreichen. Vielen Dank im Voraus. Viele Grüße Christian |
AW: Abfrage von großen Datenmengen
Ohne ins Detail zu gehen. In einem Client Server System dient der Server zur Aufbereitung der Daten, der CLient zur Pflege und Darstellung.
250000 Detaildatensätze schaut sich niemand an. Naheliegend, dass sie mit dem Reportsystem das Du verlinkt hast irgendwie weiterverarbeitet werden (sprich eingedampft). Da es um Reporting geht, scheidet eine einfache Beschränkung der Datensatzanzah aus. Ich kenn das jetzt nicht konkret, aber Du kannst die Hersteller ja mal anmailen, wie ihre Reportkomponenten mit Datenmengen > 100000 Records umgehen... Wenn Du das ganze Verfahren nicht ändern kannst, empfehle ich einen genaueren Blick auf die Detaildaten. Vielleicht kann man hier mit Teilaggregationen arbeiten, Spalten weglassen usw. und so irgendwie auf Datenmengen kommen, die clientseitig verarbeitet werden können. |
AW: Abfrage von großen Datenmengen
Zitat:
|
AW: Abfrage von großen Datenmengen
Zitat:
Ich glaube, dass mit den TSQLDataSet funktioniert auch nicht, da Sie unidirektional sind, aber der Reportbuilder bi-direktionale DataSet benötigt. Zitat:
![]() Vielleicht habe ich es auch falsch verstanden. Gibt es sonst noch eine Möglichkeit, das Caching von ClientDataSets in eine Datei auszulagern? Viele Grüße Christian |
AW: Abfrage von großen Datenmengen
Ich weiß, das Nachbohren nervt: Werden wirklich 250.000 Datensätze im Report dargestellt und muss das so sein? "Äh, die wollen das so" ist zunächst keine Antwort. Man kann ja auch mal anmerken, das es Probleme bereitet.
Wenn JA (weil z.B. Niemand nachdenken will, warum, und Du den Rotz ausbaden musst), dann geht es ja eigentlich nur um den Auftrag, diesen Mumpitz zu produzieren. Hier sollte man sich überlegen, ob man nicht anderweitig, also ohne diesen Reportbuilder, zum Ziel kommt. Das geht z.B. über Exportfunktionen des RDBMS: Die Daten werden also vom DB-Server direkt in eine Datei geschrieben (z.B. EXCEL). Dann muss sich der Endanwender eben rumschlagen, wie er die 250k-Zeilen-Datei in seinen Rechner bekommt. Andererseits kenne ich keinen Reportbuilder (und auch keinen Anwendungsfall), bei dem man durch diese Datenmassen scrollen muss. Die Vorgabe, beliebig viele Daten anzeigen zu können, ergibt sich meistens aus der Tatsache, das die Anwendung bestimmte Funktionen nicht bietet, die Anwender jedoch bestimmte Probleme lösen müssen. Ich habe gerade konkret solche Fälle, bei denen es um die Massenkorrektur von Daten geht. Die Daten müssen auf Eingabefehler oder Inkonsistenzen geprüft werden. Das kann die Anwendung nicht, also haben sich die Sachbearbeiter den Trick ausgedacht: Daten laden, als XLS-exportieren, in EXCEL öffnen und filtern/sortieren, um Probleme zu erkennen, dort korrigieren und als CSV speichern. Dann wird aus der CSV-Datei über RegEx eine Datei mit 100.000 UPDATE-Befehlen erstellt, die dann zum DB-Server geschickt wird. Toll, gell? Das Problem ist also hier z.B. das Fehlen einer direkten Exportfunktion, ohne Umweg über das Grid oder gleich das Richtige Datenvalidierungs- und korrekturtool. Deshalb ist es so immens wichtig, den genauen Grund zu erfahren, wieso irgendwo 250k Datensätze aufgelistet werden müssen. Na, und wenn darauf bestanden wird, durch 250k Datensätze zu scrollen, dann baut man eben einen Pagingmechanismus, das sollte doch wohl gehen. |
AW: Abfrage von großen Datenmengen
Hallo,
nachbohren nervt nicht, ist manchmal auch sehr wichtig.:) Ich habe mir mal die Daten, genau angeschaut. Im Master steht ein Datensatz, welcher nur Überschriften enthält. Im Detail sieht es noch schlimmer aus. Hier werden alle Datensätze kombiniert zusammengefasst. Dies bedeutet die 250 000 Datensätze setzen sie z.B. wie folgt zusammen: 250 000 Buchungen = (Mandant A * 200 Buchungen) + (Mandant B * 300 Buchungen) + (Mandant C * 300 Buchungen) + ... + ... Aufgrund dessen habe ich mal genauer nachgefragt, wie man so eine Datenhaltung rechtfertigt :) Die Antwort: Ist das es mehrere Ausgaben (Listen, Tabellenkalkulation und noch 5 weitere) im System gibt und daher die Daten so abgelegt werden. Der Reportbuilder soll nur die ERP-Software im neuen Jahrtausend willkommen heißen, damit die Auswertungen gleich an die Mandanten in schöner Form geschickt werden können, also als Brief oder Email. Gerade mit den 250 000 Datensätzen wären das ca. 3-15 Seiten pro Mandant, die geniert werden sollen. Was ja wieder human ist und sich auch jemand durchliest. Dennoch wird die Master-Detail-Beziehung benötigt, weil es andere Reports gibt, die wirklich nicht nur einen Master-Datensätz haben, sondern das Prinzip der Master-Detail-Beziehungen folgen. Im Moment könnte ich nur :kotz:, weil ich seit 5 Tagen nichts anderes mache. Und keinen Millimeter voran komme. Viele Grüße |
AW: Abfrage von großen Datenmengen
Liste der Anhänge anzeigen (Anzahl: 1)
Dann frag ich auch noch mal nach, warum du nicht die MyDAC-Komponenten von DevArt nimmst? damit ist es ein Kinderspiel und es gibt auch keine Fehler. (gerade mit deinem Projekt getestet)
MyConnection1: Username, Password, Server, Port und Database eintragen LoginPrompt = false Connected = true MyQuery1: SQL = SELECT * FROM MANDANT; Connection = MyConnection1 Active = true MyDataSource1: Dataset = MyQuery1 dbgrdMaster: DataSource = MyDataSource1 MyQuery2: SQL = SELECT * FROM BUCHUNGEN; MasterSource = MyDataSource1 MasterFields = Mandant DetailFields = Mandant Connection = MyConnection1 Active = true MyDataSource2: DataSet = MyQuery2 dbgrdDetail: DataSource = MyDataSource2 |
AW: Abfrage von großen Datenmengen
Sieht ja nicht schlecht aus.
Bin schon seit gestern am überlegen. Haben halt erst vor 4 Monaten die gesamten DBExpress Treiber für MySQL, Oracle und SQL Server gekauft, daher wird mein Chef nicht unbedingt erfreut sein, wenn ich schon wieder was will. Aber das ist ein anderes Problem. Daher meine Frage: Reicht auch der ![]() Viele Grüße Christian |
AW: Abfrage von großen Datenmengen
Sollte eigentlich mit denen auch funktionieren... Man kann sich aber auch Trial-Versionen herunterladen und testen... Das würde ich mal vorschlagen ;-)
|
AW: Abfrage von großen Datenmengen
Zitat:
Viele Dank nochmal an alle die mir geholfen haben. Viele Grüße Christian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:57 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