Autor Beitrag
ssb-blume
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 375
Erhaltene Danke: 7

XP, W7, W8
Deutschland
BeitragVerfasst: Sa 03.05.14 17:31 
Hallo
Ich habe eine Datenbank unter SQlite. Darin ist eine Tabelle mit 69000! Einträgen.
Wenn ich die diese Tabelle ins Datagrid schreibe, dauert es unzumutbar lange. Scheinbar werden alle Daten in den Ram geladen.
Natürlich brauche ich nur die Daten, die im Grid angezeigt werden (dann scrollen..) .
Was muß ich einstellen, damit nicht alle Daten auf einmal gelsen werden?
-Habe keine Ahnung-

Hansi


Moderiert von user profile iconMartok: Topic aus Datenbanken verschoben am Sa 03.05.2014 um 23:01

_________________
Brain: an apparatus with which we think we think.
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 03.05.14 18:27 
Ich kann kein Delphi, komme von der C#-Fraktion, daher kann ich nicht konkret helfen.
Außerdem denke ich, dass der Code, wo du abfragst, der Delphi-Fraktion hier sehr helfen wird, das Problem zu lokalisieren.


Aber ich vermute mal, dass es daran liegt, dass du die Daten im Code anforderst und zuerst in ein Array (oder ähnliches) ziehst, denn 69k Datenzeilen klingen vielleicht viel, ist es aber nicht.
Das ist natürlich langsam, wenn z.B. nur die ersten 10 Zeilen gebraucht werden. Die Datenbank schickt nämlich Zeile für Zeile raus, sobald sie verfügbar ist, sie sammelt nicht erst alles zusammen und schickt es dann auf einen Schlag - zumindest würde es mich sehr wundern.

Im .NET-Framework gibt es ein Interface namens IEnumerator. Das erlaubt es, durch die angeforderten Daten hindurch zu iterieren. Der Vorteil dabei ist, dass du bei dem ersten Datensatz anfängst, die Folgenden aber noch gar nicht da sein müssen. Fragst du den zweiten Datensatz ab, musst du nur so lange warten, bis genau der da ist, Weitere sind dabei unwichtig. Die ersten 10, 20, 100, oder 1000 Datensätze lassen sich schnell durch laufen und alle Weiteren werden im Hintergrund geladen, bis sie gebraucht werden.
Ich wette, bei Delphi gibt es etwas vergleichbares.

Der Fehler sieht dann vermutlich so aus, dass du mit dem Enumerator durch alle Elemente durch iterierst und Diese dann irgendwo sammelst, bevor du sie verwendest.
Das sammeln kostet natürlich Zeit.


Zusätzlich dazu gibt es bei SQL noch das kleine Schlüsselwort "TOP".
Du setzt das gefolgt von der Anzahl Datensätze hinter das SELECT und bekommst dann auch nur so viele Datensätze, wie du gefordert hast.

Problem an der Sache:
Immer, wenn du mehr haben musst, dann ist eine neue Datenbankabfrage nötig und auch das kostet zusätzlich Zeit.
Es ist daher (natürlich je nach Anwendungsfall) effektiver, alle benötigten Daten auf einmal zu fordern, aber nicht auf das Eintreffen aller Daten zu warten.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 03.05.14 18:35 
Benutzt du ein TDBGrid?
ssb-blume Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 375
Erhaltene Danke: 7

XP, W7, W8
Deutschland
BeitragVerfasst: Sa 03.05.14 19:50 
Hier etwas Code:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
dbGrid.DataSource = bindingSource1;
dataAdapter = new SQLiteDataAdapter(sql, db.connM);
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
dataAdapter.Fill(table); // <- dauert etwaa 1,5 s
bindingSource1.DataSource = table; // <- dauert etwa 1,5 min!

auch das Sortieren (Klick auf Spaltenheader) dauert, aber viel länger als das laden.

Ja, es ist nicht Delphi sondern C#.

Hansi

Moderiert von user profile iconTh69: C#-Tags hinzugefügt

_________________
Brain: an apparatus with which we think we think.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 03.05.14 20:20 
Das dataAdapter.Fill hat bereits alle Daten in den Ram geladen das ist also nicht das Problem.
Was hängt alles an der BindingSource was hängt alles an ~Scroll~ oder Paint Events der Beteiligten (BindingSource, DataTable, Controls etc.)?

Wenn du nicht alles auf einmal in den Ram laden willst dann benutz ein SQL das nicht alle Daten lädt und sende dann entsprechend angepasstes SQL beim scrollen durch die Datenmenge so wie es dann benötigt wird. Aber mal anders gedacht. Warum überhaupt einfach so viele Daten laden? Als User dieser Anwendung würde ich mich fragen warum die mich mit so vielen Daten allein lässt. Eine hilfreiche Anwendung würde den Anwender mit ensprechenden Such/Filter oder sonstigen Einschränkungsmöglichkeiten beistehen so das er nur mit Datenmengen konfrontiert wird die man auch sinnvoll überblicken kann. Und das sollten vielleicht ein paar Dutzend Datensätze sein wenn schwierig wird vielleicht auch eine ganz kleine 3stellige Zahl. Aber beim mehr könnt ich auch gleich Excel nehmen ;)
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Sa 03.05.14 21:11 
Nimm kein DBGrid, sondern ein normales. Programmiere das Füllen des Grids einfach selbst ...

user profile iconssb-blume hat folgendes geschrieben Zum zitierten Posting springen:
auch das Sortieren (Klick auf Spaltenheader) dauert, aber viel länger sls das laden


... dann kannst du auch SQLite sortieren lassen. Wenn du dann noch einen Index auf die entsprechende Spalte hast, dann dauert das Sortieren exakt garkeine Zeit mehr (weil es schon entsprechend sortiert vorliegt).

Soweit ich das sehe unterstützt das TDBGrid kein Lazy Loading, aber so genau weiß ich das auch nicht (weil ichs nie benutze ;) ). SQLite kann dir aber exakt die entsprechenden Zeilen geben, die du brauchst (siehe hier)

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 03.05.14 21:51 
@Xion : Es geht nicht um Delphi.
ssb-blume Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 375
Erhaltene Danke: 7

XP, W7, W8
Deutschland
BeitragVerfasst: So 04.05.14 08:46 
Vielen Dank Ralf Jansen,

Du hast Recht. es sind wirkliche sehr viele Daten, die dem User um die Ohren geschlagen werden. Man ist eben etwas Betriebsblind.
Natürlich git es mindestens 4 mögliche Sortierungen, die das Angebot sehr stark einschränken.
Ich werden also alles neu machen und dies beachten.

Xion:
Dies habe ich versucht. Geht aber nicht mit [LIMIT integer [( OFFSET | , ) integer]], da die Offset-Angabe keine Ausgabe bewirkt.
Außerdem ist es doch sehr mühselig, jede Änderung des Selects zu prorammieren.

Also an alle: Vielen Dank!

Hansi

_________________
Brain: an apparatus with which we think we think.