Hi,
For last few hours I was working on a problem with bad performance and memory problems with such a simple query:
select prod from Product prod order by prod.id ASC
Right now I have 55541 'Product' (attached to this post) entities in database and I'm trying to speed listing them with paging. The problem is, that running code that looks like this:
TypedQuery<Product> icQuery = em.em.createQuery("select prod from Product prod order by prod.id ASC", Product.class); prodList = icQuery.setFirstResult(start).setMaxResults(count).getResultList();
is quite slow. Well, after first request and "warming up" database file, query runs for about 1.5 (best) to 6 (worst) sec:
2011-11-15 19:30:59.578 [http-bio-8080-exec-3] DEBUG pl.hplxtool.dao.impl.ProductDAOImpl - Query: [select prod from Product prod order by prod.id ASC] 2011-11-15 19:30:59.578 [http-bio-8080-exec-3] DEBUG pl.hplxtool.dao.impl.ProductDAOImpl - Executing query 2011-11-15 19:30:59.578 [http-bio-8080-exec-3] DEBUG pl.hplxtool.dao.impl.ProductDAOImpl - Start: 250, count: 50 2011-11-15 19:31:03.219 [http-bio-8080-exec-3] DEBUG pl.hplxtool.dao.impl.ProductDAOImpl - Query executed 2011-11-15 19:31:03.220 [http-bio-8080-exec-3] DEBUG pl.hplxtool.dao.impl.ProductDAOImpl - Returning data
Query manager builds plan like this:
[2011-11-15 19:30:59 #269 query.manager] <queryRequest query="select prod from Product prod order by prod.id ASC" args="null" transactionId="-1" /> [2011-11-15 19:30:59 #270 query.manager] <newQueryProgram> <orderPlan plan="sort(fetch(index(-279[all])))" eval="9.3782" var="1" prm="0" reg="0" order="prod.id"> <fatchPlan plan="fetch(index(-279[all]))" eval="7.4751" var="1" prm="0" reg="0"> <btreePlan plan="index(-279[all])" eval="6.174" var="1" prm="0" reg="0" variable="prod" /> </fatchPlan> </orderPlan> </newQueryProgram> [2011-11-15 19:30:59 #271 query.manager] <newQueryResponse isUnique="false" resultSize="50" fetchSize="55541"> <SimpleResultBuilder name="prod" type="pl.hplxtool.model.Product" /> </newQueryResponse>
ODB server in newest (2.3.3_04) version is running with bigger heap size - now it's 384MB.
I was trying to build wrapper object ProductTO that contains only fields that I need in listing and the use new ProductTO() in query. Didn't help - I always get OutOfMemory exception. The interesting part is that running this query needs lots of memory at tomcat side (attached screenshot) and after running it 3-4 times in a row cause java.lang.OutOfMemoryError: Java heap space exception. The same query in Explorer runs blazing fast (22ms) but I think it's because Explorer lazy loads all that objects and load their content on demand.
ODB is running as server and I'm using loopback to connect to this server.
So, how else can I speed up this type of query? Or maybe I just need to add some more heap space for ODB server (database is 560MB large)?