views:

154

answers:

1

I use JBoss EJB 3.0 implementation (JBoss 4.2.3 server) At the beginning I created native query all the time using construction like

Query query = entityManager.createNativeQuery("select * from _table_");

Of couse it is not that efficient, I performed some tests and found out that it really takes a lot of time... Then I found a better way to deal with it, to use annotation to define native queries:

@NamedNativeQuery( name = "fetchData", value = "select * from _table_", resultClass=Entity.class )

and then just use it

Query query = entityManager.createNamedQuery("fetchData");

the performance of code line above is two times better than where I started from, but still not that good as I expected... then I found that I can switch to Hibernate annotation for NamedNativeQuery (anyway, JBoss's implementation of EJB is based on Hibernate), and add one more thing:

@NamedNativeQuery( name = "fetchData2", value = "select * from _table_", resultClass=Entity.class, readOnly=true)

readOnly - marks whether the results are fetched in read-only mode or not. It sounds good, because at least in this case of mine I don't need to update data, I wanna just fetch it for report. When I started server to measure performance I noticed that query without readOnly=true (by default it is false) returns result with each iteration better and better, and at the same time another one (fetchData2) works like "stable" and with time difference between them is shorter and shorter, and after 5 iterations speed of both was almost the same...

The questions are:

1) is there any other way to speed query using up? Seems that named queries should be prepared once, but I can't say it... In fact if to create query once and then just use it it would be better from performance point of view, but it is problematic to cache this object, because after creating query I can set parameters (when I use ":variable" in query), and it changes query object (isn't it?). well, is here any way to cache them? Or named query is the best option I can use?

2) any other approaches how to make results retrieveng faster. I mean, for instance I don't need those Entities to be attached, I won't update them, all I need is just fetch collection of data. Maybe readOnly is the only available way, so I can't speed it up, but who knows :)

P.S. I don't ask about DB performance, all I need now is how not to create query object all the time, so use it efficient, and to "allow" EJB to do less job with the same result concerning data returning.

Added 15.03.2010:
By query I mean query object (so how to cache this object to reuse); and to cache query results is not a solution for me because of where cause in query can be almost unique for each querying because of float-pointing parameters there. Cache just will not understand that "a > 50.0001" and "a > 50.00101" can give the same result, but also can not.

A: 

You could use second level cache and query cache to avoid hitting the database (works especially well with read-only objects). Second level cache is supported by Hibernate (with a third party cache provider) but is an extension to JPA 1.0 though.

Pascal Thivent
Thank you for replying.I can't avoid hitting DB in many cases, because I have mlns of data in table, and what I fetch depends on input parameters, and because of float-point input data in most cases selects with parameters in where clause will be unique. It won't be enough memory to cache it... That's why I try to optimize EJB/Hibernate code as much as possible (query creation; data transformation...)
Maxym
and what could be cached I did it my own way, so second level cache can be another option for my caching strategy... Thanks!
Maxym
@Maxym *"selects with parameters in where clause will be unique"* Ah, I see and, indeed, query cache won't be a solution then. But this wasn't obvious in the question. Maybe you should mention that.
Pascal Thivent
@Pascal Thivent: you are right, I've added some short explanation. Thank you
Maxym