# Hibernate, JTable und Performance



## Guest (22. Jul 2008)

Guten Morgen,

wusste nicht ob ich meinen Thread in Datenbankprogrammierung oder Swing packen sollte - Performance Unterforum gibbet ja nicht mehr. Also Sorry fals falsch gepostet!

Zu meinem Anliegen:
Ich lese mir aus einer Datenbank derzeit ~10.000 Datensätze mit Hibernate aus einer MySQL DB.
Ausgelesen werden die Daten über 
	
	
	
	





```
Session.createQuery("select o from Object o").list();
```

Was ich schön an Hibernate find, ist dass er mir gleich eine List mit den Objekten zum Arbeiten übergibt,
allerdings frage ich mich im Moment ob dies nicht eher mein Problem darstellt, da ich derzeit 
ziemliche Performance Probleme bekomme.

10.000 Datensätze in phpMyAdmin anzeigen dauert nur wenige Millisekunden, das auslesen mit Hibernate 
dauert ~15 Sekunden. Sind die Daten dann in der JTable gelandet (die Liste wird im Model hinterlegt) ist auch das navigieren durch die JTable nicht unbedingt das schnellste ...

Von solchen Dingen wie Sortierung über die TableHeader oder dergleichen einmal ganz abgesehen, das ist nämlich unzumutbar (könnte mir fast nen Kaffee holen in der Zeit)

Hatte eben kurz daran gedacht ob das Programm vllt. schneller laufen würde wenn man anstatt der HibernateObjekte sich eine List<HashMap<String, String>> aus der Db liest per Hibernate und die Werte direkt so an das Model gibt - hat jemand ne Idee ob dies vllt. schneller gehen würde?

Andere Variante über die ich nachgedacht hatte war, die Daten "Häppchen Weise aus der DB zu ziehen".
Also den ersten Select mit einem Limit von 5000 absetzen und wenn die Daten in die DB gelangen im Hintergrund die restlichen Daten nachladen und an die Liste anhängen.

Auch das nachladen der Datem beim Scrollen wie es z.B. schon auf der Seitze dzone.com zu sehen ist finde ich eigentlich recht interessant, allerdings wüsst ich nicht wie ich das ganze dann mit dem sortieren oder dergleichen lösen könnte/und oder sollte ...

Hat sonst jemand Tipps wie und wo man einiges an Performance gut machen kann im Bezug auf Hibernate und die JTable mit TableModels?


----------



## FArt (22. Jul 2008)

Tipp: bevor das große Raten losgeht: nimm einen Profiler und schau dir an, wo die Zeit bleibt.

Ist es das SQL Statement oder fehlende Indexe auf der DB, oder ist es, weil so viele Datensätze im Speicher hängen bei zu geringem Heap, zu viele GCs, ....


----------



## Guest (22. Jul 2008)

FArt hat gesagt.:
			
		

> Tipp: bevor das große Raten losgeht: nimm einen Profiler und schau dir an, wo die Zeit bleibt.



Ja sicherlich ein Schritt den ich heute noch gehen werde, aber schon beim Debuggen ist mir aufgefallen das der Befehl "Query.list()" nicht unbedingt der schnellste ist ...

Indizes existieren im übrigen auf der Tabelle.


----------



## foobar (22. Jul 2008)

10 000 Datensätze mit Hibernate auslesen ist auf jeden Fall langsamer als handgeschriebenes SQL. Das ist ja klar. In so einem Fall leidet die Performance unter dem Hibernateoverhead. 
Du kannst da aber noch einiges optimieren. In der Hibernatedoku gibts jede Menge Tips zum Performancetuning z.b. Paging.


----------



## byte (22. Jul 2008)

Die Performance wird in diesem Fall aber auch nicht schlechter sein, als wenn Du entsprechendes Select-Statement absetzt und das Ergebnis in Objekte verpackst.
Genau weisst Du es aber, wenn Du einfach mal die Performance des reinen SQL-Statements testest. Wenn das auch so lange dauert, kannst Du nur bei der DB versuchen zu optimieren.

Generell würde ich es aber vermeiden, Tabellen mit so vielen Datensätzen anzuzeigen. Der User ist eh überfordert mit so großen Tabellen. Du könntest das Problem z.B. lösen, indem Du einen Pagable Table verwendest oder (falls sich das anbietet) einen TreeTable benutzt, der Kind-Elemente lazy nachlädt.


----------



## Guest (22. Jul 2008)

byto hat gesagt.:
			
		

> z.B. lösen, indem Du einen Pagable Table verwendest



Gibt es da iwo etwas fertiges was auch mit Sortieren etc. pp. funktioniert?

Im besten Fall vllt. sogar etwas das nicht unbedingt mit verschiedenen Pages arbeitet sondern die Daten beim Scrollen aktualisiert?


----------



## FArt (22. Jul 2008)

Noch mal der Tipp: auf Verdacht optimieren ist Käse. Stelle sicher, dass genau das dein Problem ist!


----------



## ARadauer (22. Jul 2008)

> 10 000 Datensätze mit Hibernate auslesen ist auf jeden Fall langsamer als handgeschriebenes SQL. Das ist ja klar. In so einem Fall leidet die Performance unter dem Hibernateoverhead.


na super ich bin gerade dabei, mein produkt wartungstool, das  rund 2 mio datensätze ließt, bearbeitet und schreibt, auf hibernte umzubauen... na das kann ich mir ja dann wohl sparen.....


----------



## BjörnBu (22. Jul 2008)

ARadauer hat gesagt.:
			
		

> > 10 000 Datensätze mit Hibernate auslesen ist auf jeden Fall langsamer als handgeschriebenes SQL. Das ist ja klar. In so einem Fall leidet die Performance unter dem Hibernateoverhead.
> 
> 
> na super ich bin gerade dabei, mein produkt wartungstool, das  rund 2 mio datensätze ließt, bearbeitet und schreibt, auf hibernte umzubauen... na das kann ich mir ja dann wohl sparen.....



Ich wüsste nicht wieso. Natürlich erzeugt hibernate overhead. Dank lazy-loading und cache-Unterstützung gewinnst du grade bei vielen Dantensätzen eher gegenüber reinem JDBC. Du hast zwar Overhead und DIE Lösung für große Datenmengen ist hibernate wohl kaum aber es lässt sich durchaus nutzen und bietet auf einem gewissem level auch echte Vorteile.

Will man aber von Partitioning profitieren, muss man andererseits aber meißt auf die standart-Methoden verzichten. Aber zumindest bisher habe ich mit der Criteria API immer bessere Ergebnisse erziel, als mit meinem JDBC Wissem möglich war. Allerdings habe ich erst einmal mit so vielen Datensätzen gearbeitet und in deisem Fall nur lesende Zugriffe gehabt


----------



## SnooP (22. Jul 2008)

oder auch nicht, weil es einfach nicht stimmt.

Hibernate macht doch auch keine Hexerei - wenn das handgeschriebene SQL in ein Result-Set gepackt wird und man nur bestimmte Spalten ausliest und nur Strings darstellt - dann ist das JDBC vermutlich schneller, weil weniger große Objekte gebaut werden müssen... wenn man aber sowieso Objekte nutzt um die Daten aus der DB zu halten, fährt man mit Hibernate besser, weil es das manuelle JDBC und SQL-String rumgefrickel entfernt... zusammen mit Spring+HibernateTemplate hat man sehr schöne Mechanismen um den ganzen Zugriff nochmals zu kapseln...

das einzige was mit Hibernate sicher nicht so schön ist, sind Massenupdates... wobei auch hier schon einige Dinge verbessert wurden... ich werde das in meinem aktuellen Projekt wohl noch mal ausprobieren. 

Zur Pagination und auch Scrollable iteration (wie das einige DB-Tools zur Darstellung von Tabellen-Inhalten auch machen) siehe die Hibernate-Doku... allerdings weiß ich nicht, ob der JDBC-Treiber für MySQL Scrollable Interation bereitstellt.


----------



## byte (22. Jul 2008)

Anonymous hat gesagt.:
			
		

> Gibt es da iwo etwas fertiges was auch mit Sortieren etc. pp. funktioniert?



In Sachen Webentwicklung gibts da ziemlich geile Sachen, aber für Swing hab ich noch nichts dergleichen gesehen. Wichtig ist, dass sowohl Paging als auch Sortierung durch Hibernate passiert.

@Hibernate Performance: http://www.hibernate.org/15.html


----------



## Gast (22. Jul 2008)

Derzeit habe ich in meinem TableModel immer eine Liste mit meinen jeweiligen Objekten (z.B. 10.000 Objekte vom Typ MyObject)

In der getValueAt Mothe hole ich mir die Werte dann immer über List.get(pRow).getXYZ(); - bin am überlegen ob ich mir vllt. die Zeit spare hier komplette Objekte erstellen zu lasen (beim select über hibernate) und mir einfach nur ein Object[] an Daten anzeigen lasse in der JTable ...

Macht zwar einiges komplizierter an Code, aber ich schätze mal das die Performance einiges zu legen könnte ...


----------



## FArt (22. Jul 2008)

Gast hat gesagt.:
			
		

> Derzeit habe ich in meinem TableModel immer eine Liste mit meinen jeweiligen Objekten (z.B. 10.000 Objekte vom Typ MyObject)
> 
> In der getValueAt Mothe hole ich mir die Werte dann immer über List.get(pRow).getXYZ(); - bin am überlegen ob ich mir vllt. die Zeit spare hier komplette Objekte erstellen zu lasen (beim select über hibernate) und mir einfach nur ein Object[] an Daten anzeigen lasse in der JTable ...
> 
> Macht zwar einiges komplizierter an Code, aber ich schätze mal das die Performance einiges zu legen könnte ...



„More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. „
William Allan Wulf


----------



## Guest (23. Jul 2008)

FArt hat gesagt.:
			
		

> „More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. „
> William Allan Wulf



Sachmal Kollege, hast du eigtl. auch iwas Sinnvolles beizutragen? Ich hab dir schon beim ersten mal gesagt das ich mit dem Profiler arbeite(n werde) und hatte das gestern auch den ganzen Tag getan.

Und was hatte ich gesehen => Query.list() ist - wenn er über viele einzelne Datensätze gehht mit sum() und avg() Kram ratten lahm - weswegen ich auch schon diesen Thread erstellt hatte!

Schneller gehts tatsache ein klein wenig wenn ich nur mit Object[] arbeite anstatt mir von Hibernate meine Objekte sofort immer erstellen zu lassen - ist halt nur bei weitem nciht so komfortabel ...

Vllt. noch jemand der ein paar Beispiele zur Pageable Table oder dem nachladen von Daten hat?
Nehm ich auch gerne Erfahrungsberichte WANN die Daten am besten gelesen werden sollten, also z.B.:
Erstmal 1000 und dann im Hintergrund munter fröhlich die restlichen Daten ziehen etc. pp. ...


----------



## byte (23. Jul 2008)

Wie ich oben schon geschrieben habe solltest Du erstmal überprüfen, ob Du mit reinem SQL wirklich schneller bist als mit Hibernate. Und dann kannst Du daran arbeiten, Deine HQL bzw. Criteria-Queries zu optimieren. Mit Object[] zu arbeiten halte ich für recht sinnfrei. Das ist Micro-Optimierung, weil Du maximal das Erzeugen und Verpacken der Objekte sparst. Wenns danach geht kannst Du auch gleich auf Objektorientierung pfeifen...

Einen Pagable Table zu bauen, ist wirklich nicht schwierig. Einfach die Anzahl Zeilen begrenzen (z.B. auf 100) und entsprechende Buttons für Vor, Zurück, Anfang, Ende einbauen. Idealerweise zeigt er auch noch die Gesamtanzahl Einträge an. Mit Hilfe der Seitenzahl kannst Du dann mit Hibernate das entsprechende Ergebnis holen.

http://www.hibernate.org/314.html


----------



## FArt (23. Jul 2008)

Anonymous hat gesagt.:
			
		

> Und was hatte ich gesehen => Query.list() ist - wenn er über viele einzelne Datensätze geht mit sum() und avg() Kram ratten lahm - weswegen ich auch schon diesen Thread erstellt hatte!



Das ist eine Infromation, die du bis jetzt vorenthalten hast. Jetzt muss nicht mehr geraten werden wo das Problem liegt. Besonders der unklare Zusammenhang zur JTable... es geht wohl doch nur um die Query, oder? Dennoch ist die Messung der list() Methode noch nicht feingranular genug. Was passiert denn da drinnen genau?

byto hat das wichtigste sonst schon gesagt.

Stecken sum() und avg() in der Query oder im Javacode? Ist genau diese Query in plain SQL mit genau diesen Daten signifikant schneller?


----------



## Guest (23. Jul 2008)

FArt hat gesagt.:
			
		

> Anonymous hat gesagt.:
> 
> 
> 
> ...


----------



## byte (23. Jul 2008)

Was soll das heissen? Das von Hibernate generierte SQL ist in phpmyadmin schneller? Wohl kaum.

Hast Du Dir das von Hibernate generierte SQL überhaupt mal angeguckt? Poste es doch mal, dann sehen wir weiter.


----------

