# Größe eines ResultSets



## jan.ul (17. Sep 2007)

Hallo zusammen,

ich habe eine Abfrage auf eine ziemlich große Datenbank, deren Ergebnismenge bei ca 1 Mio Sätzen ca 600 MB groß sein wird, wobei gar nicht auf einmal benötige sondern nach und nach verarbeiten möchte. Nun befürchte ich, dass die gesamten Sätze auf ein Mal in das ResultSet eingelesen werden und mir dabei das ResultSet, bzw der Speicher voll laufen werden.
Gibt es eine Möglichkeit, dass man die Sätze immer nur häppchenweise einliest und verarbeitet?
Was mich sonst noch interessieren würde: Bis zu welcher Größe sind ResultSets noch händelbar?


viele Grüße,

Jan


----------



## tuxedo (17. Sep 2007)

Hilft dir das Stichwort "LIMIT" vielleicht weiter?


```
SELECT *
FROM `account`
LIMIT 0 , 30
```

Damit kannst du häppchenweise das Ergebnis deiner Anfrage eingrenzen...

- Alex


----------



## sparrow (17. Sep 2007)

Soweit ich weiss hast du keine Probleme.
Mit ResultSet.next() holst du den nächsten Datensatz, vorher befindet der sich nicht im Speicher.
Also wenn du jeden Datensatz direkt abarbeitest dürftest du keine Probleme haben.

Gruß
Sparrow


----------



## SlaterB (17. Sep 2007)

wat, für jedes Ergebnis ein DB-Zugriff?
wird ja wohl hoffentlich gepuffert sein?


----------



## sparrow (17. Sep 2007)

Ich habe bisher nur bei einem Projeht mitgearbeitet bei dem die Tabellen so groß waren, dass man sich um so etwas Gedanken machen muss. Dort wurde PostgreSQL als Datenbank eingesetzt.
Ich denke mal das buffern wird in diesem Fall die Datenbank übernehmen, sozusagen eine temporäre Tabelle erstellen und deren Datensätze auf Anfrage rüberschickt.
Die eigentliche Selektion ist zu diesem Zeitpunkt ist zu diesem Zeitpunkt schon gelaufen.

So mein Gefühl.


----------



## jan.ul (17. Sep 2007)

@ Alex: Das mit dem Limit habe ich heute auch schon mal gefunden, aber schränkt das nicht mein gesamtes Ergebnis auf 30 Sätze ein? Das würde ich so ja nicht wollen, an sich brauche ich ja schon alle Sätze, nur halt nicht auf ein mal.
@ sparrow: Danke für deine Einschätzung. Wenn Java und die Datenbank dahinter (DB2 V8) so clever sind, dass die das von selbst händeln, dann wäre das natürlich das bequemste. Stellt sich nur die Frage, ob die das tatsächlich so machen. Da werde ich wohl mal probieren müssen...

viele Grüße,

Jan


----------



## maki (17. Sep 2007)

> Da werde ich wohl mal probieren müssen...


Das würde ich dir auch empfehlen, je nach JDBC Treiber und DB kann es da riesige Unerschiede in Sachen Performance geben.

Wie greifst du denn auf die DB zu?
Wenn du SQL brauchst, kann ich dir iBatis empfehlen.


----------



## tuxedo (17. Sep 2007)

@jan.ul

Du Held... du kannst Limit doch einstellen... ;-)

0, 30 bedeutet: alles von 0 bis 30 ...

Wenn du jetzt 10000 Zeilen in deinem ergebnis hast, kannst du dein Statement mit Limit jetzt so manipulieren, dass beispielsweise in 10 Schritten je 1000 Zeilen geholt werden.

Somit hättest du deine 10000 Zeilen in 10 Anfragen unterteilt ohne die Anfrage selbst mit einem komplizierten where zu aufzusplitten.

Die genaue LIMIT Syntax kannst du ja nachlesen. Aber prinzipiell ist das genau das, was du verlangt hast.


----------



## tfa (17. Sep 2007)

alex0801 hat gesagt.:
			
		

> Die genaue LIMIT Syntax kannst du ja nachlesen. Aber prinzipiell ist das genau das, was du verlangt hast.



Man sollte noch erwähnen, dass LIMIT kein Standard-SQL ist (ja, es gibt mehr RDBMS als MySQL).

Trotzdem ist es nicht besonders effektiv, statt einer bspw. 10 limitierte Abfragen abzusetzen, wenn
es in einer geht. Normalerweise öffnet man sich mit einer Query einen Cursor, mit dem man das
Resultset abarbeitet. Wieviel da vorgeladen bzw. gecachet ist grundsätzlich Sache des RDBMS und der  Einstellungen des JDBC-Treibers.

tfa


----------



## tuxedo (18. Sep 2007)

Ich hab nicht gesagt dass es die beste Lösung ist ;-) Es war nur das was er verlangt hat. Und klar: Das Limit macht erst dann Sinn, wenn das Ergebnis *wirklich* groß ist. 

Zur Sache mit dem SQL-Standard: Ja, ich bin halt von MySQL ausgegangen. Dass es noch mehr DBMS gibt müssen wir hier ja nicht diskutieren. Ich bin btw auch kein Freund von MySQL (mag den GPL-Treiber nicht).

- Alex


----------



## Guest (18. Sep 2007)

Hi,

heute morgen konnte ich auf der Arbeit zum Glück jemanden erreichen, der mir weiterhelfen konnte. Es ist tatsächlich so, dass man in Java keine Einstellungen vornehmen kann.
Die Tatsache, ob das ResultSet materialized wird, wie er es genannt hat, hängt von der Art des SQL ab. Wenn ich zB ein order by mache, für das ich alle Datensätze im Zugriff benötige wird im temporary space der Datenbank eine temporäre Tabelle aufgebaut - mein Arbeitsspeicher würde mir also nicht volllaufen. Nun gilt es für mich herauszufinden, wie sich die Performance bei einem join verhält.

viele Grüße,

Jan


----------



## sparrow (18. Sep 2007)

Anonymous hat gesagt.:
			
		

> Nun gilt es für mich herauszufinden, wie sich die Performance bei einem join verhält.



Genauso.
Im Zweifelsfall baut dir die Datenbank eine tempräre Tabelle, so zumindest meine Efahrung.
Dafür sind die Datenbanksysteme ja da.

In dem von mir angesprochenen Projekt dauert es halt eine Weile bis das ResultSet zur Verfügung steht (in unserem Fall ca. 12 Minuten auf einem sonst recht schnellen Server), dann kann das ResultSet aber ganz flink durchlaufen werden.

Die Verwendung von LIMIT macht meines Erachtens überhaupt keinen Sinn, auch nicht bei großen Datenmengen. Meine Meinung nach ist LIMIT versehentlich in den mySQL-Syntax gepurzelt weil es dann für Webseiten einfacher ist Informationen aus dem Ergebnis der Abfrage zu ziehen, sonst müsste man nämlich erst eine bestimmte Anzahl von Datensätzen "skippen", was so die Datenbank macht. Dies ist wohl aus der Verbindunge php->mySQL geboren.

Ich entwickele größtenteils mit PostgreSQL und muss zugeben, dass ich nicht mal weiß ob das LIMIT überhaupt unterstützt, ich habe es nämlich noch nie gebraucht.

Gruß
Sparrow


----------



## ms (18. Sep 2007)

Fast jede Datenbank hat eine Limit-Funktion, auch wenn sie anders heist bzw. die Syntax anders ist, wie z.B. bei Oracle. 
Da gibts das rownum Konstrukt, mit dem man dasselbe ergebnis erzielen kann. Postgresql kennt auch Limit (siehe hier)

Für Blätterlogik ist das schon sehr praktisch, wie ich finde.
In dem angesprochenen Fall würde ich es aber nicht verwenden.

ms


----------

