]
Eric Obermuhlner commented on HHH-2399:
---------------------------------------
I wonder why in DefaultAutoFlushEventListener
flushMightBeNeeded() and flushIsReallyNeeded() are separated?
All the dirty checking of the session cache happens inside flushEverythingToExecutions()
which is the only thing that happens inbetween.
Possible reason 1) flushEverythingToExecutions() is necessary for flushIsReallyNeeded() to
be correct
Possible reason 2) flushEverythingToExecutions() was considered cheap compared to
flushIsReallyNeeded()
If 2) we could measure if this is true also for large session caches (I cannot right now,
I have hibernate only setup as library).
A minor speed optimization for FlushMode.ALWAYS.
The condition in flushIsReallyNeeded() could be turned around and be written like this:
<code>
private boolean flushIsReallyNeeded(AutoFlushEvent event, final EventSource source) {
return source.getFlushMode()==FlushMode.ALWAYS || source.getActionQueue()
.areTablesToBeUpdated( event.getQuerySpaces() );
}
</code>
FlushMode.AUTO practically unusable - should not flush before EVERY
query
-------------------------------------------------------------------------
Key: HHH-2399
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2399
Project: Hibernate3
Issue Type: Improvement
Affects Versions: 3.1.3, 3.2.0.ga, 3.2.1, 3.2.2
Environment: PostgreSQL 8.1.5, JDBC 2 and 3, Linux kernel 2.4.x, 2.6.x, Java
1.5.0_09
Reporter: Piotr Kołaczkowski
Attachments: hbtest.zip
The method flushIfRequired seems to flush before every query execution, even though there
wasn't anything changed to the objects in the session, and the objects in the session
are of different class than the object(s) queried. When having more than a few such
objects in a session, it may lead to large, unneeded overheads (I noticed 10-200 times
slowdown on simple queries). Our system uses many fast queries, that uasually return only
one result or few results. The average query durations on different levels, measured by
System.nanoTime() (see the attachment):
- database level: 0.05 ms
- pure JDBC code, prepared statements: 0.2 ms
- pure JDBC code, no prepared statements: 0.7 ms
- not cached hibernate query, no other objects associated with the session: 1.3 ms
- cached hibernate query, object in the session cache, no other objects associated with
the session: 1.1 ms
- cached hibernate query, 10000 very simple objects of some other class in the session:
>50 ms
10000 may seem large, but note these were very simple objects, having only 2 properties.
On our production system we have classes with many properties, and even 20 objects in a
session can cause a sub-millisecond query to run longer than 5 ms. We switched to
FlushMode.COMMIT, and now the performance is much better.
Can you do something about this? As far as I've read in JIRA, a similar issue exists
in Hibernate 2.x, and is still OPEN / UNRESOLVED.
BTW. Why is the 1st level cache so slow in my tests? Why reading just a 2 field object
from the database cause so much overhead over pure JDBC? What am I doing wrong?
There is so much marketing about using cglib reflection optimizer in the performance FAQ
but even if I retrieved these objects using JDBC and reflection, I would achieve much
better performance. After all 1 ms is very much time, if getting results from DB and
sending them to JVM lasts 0.2 ms.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: