-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Query execution delay in class org.hibernate.AbstractBatcher
PostPosted: Thu Jan 29, 2009 3:50 pm 
Newbie

Joined: Tue Jan 27, 2009 12:43 pm
Posts: 16
I have an 8-9 second performace delay with the following query test case and Hibernate configuration. Please note that the table contains over 5M rows, and is accessed via a DB link. When I turn on trace level logging, the delay is occuring in the AbstractBatcher class as it executes the query. The query execution alone takes over 8 seconds to execute. A corresponding JDBC test case that I created takes less than a second to execute. I created the straight JDBC test case by executing the SQL statement that Hibernate generates.

The symptoms keep pointing me back to Hibernate, and specifically to the AbstractBatcher class. If the issue was a missing index or something of that nature, the JDBC version of the query would be slow also. I am using the same Oracle JDBC driver for both Hibernate and the JDBC versions.

Can anybody recommend a method for debugging this? Should I enter a JIRA?

Thanks.

Log messages:

14:35:05,509 TRACE JDBCContext:210 - after transaction begin
14:35:05,509 INFO TestQueryPerformance:60 - Creating criteria...
14:35:05,510 TRACE ThreadLocalSessionContext:300 - allowing proxied method [createCriteria] to proceed to real session
14:35:05,522 INFO TestQueryPerformance:71 - Executing query...
14:35:05,537 DEBUG AbstractBatcher:366 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
14:35:05,538 DEBUG SQL:401 - select * from ( select
Hibernate: select * from ( select
14:35:05,539 TRACE AbstractBatcher:484 - preparing statement
14:35:05,766 TRACE StringType:133 - binding 'value6' to parameter: 1
14:35:05,768 TRACE StringType:133 - binding 'value1' to parameter: 2
14:35:05,769 TRACE StringType:133 - binding '%value3%' to parameter: 3
14:35:13,149 DEBUG AbstractBatcher:382 - about to open ResultSet (open ResultSets: 0, globally: 0)
14:35:13,151 TRACE Loader:694 - processing result set
14:35:13,153 DEBUG Loader:699 - result set row: 0

Hibernate version:

3.2.4.sp1.cp03

Config settings:

hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.transaction.factory_class=org.hibernate.transaction.JDBCTransactionFactory
hibernate.current_session_context_class=thread
hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider

Database:

Oracle 10g

Mapping documents:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="mypackage.MyTable" mutable="false" table="mytable@myschema">
    <!-- Specify primary key. This is required to run Hibernate queries with criteria. -->
            <id name="pkey" type="big_decimal">
                <column name="PKEY" precision="22" scale="0" />
            </id>
            <property name="dbcolumn1" type="string">
                <column name="DBCOL1" length="50" />
            </property>
            <property name="dbcolumn2" type="string">
                <column name="DBCOL2" length="30" />
            </property>
            <property name="dbcolumn3" type="string">
                <column name="DBCOL3" length="100" />
            </property>
            <property name="dbcolumn4" type="string">
                <column name="DBCOL4" length="60" />
            </property>
            <property name="dbcolumn5" type="string">
                <column name="DBCOL5" length="45" />
            </property>
            <property name="dbcolumn6" type="string">
                <column name="DBCOL6" length="2" />
            </property>
            <property name="dbcolumn7" type="string">
                <column name="DBCOL7" length="40" />
            </property>
            <property name="dbcolumn8" type="string">
                <column name="DBCOL8" length="10" />
            </property>
            <property name="dbcolumn9" type="string">
                <column name="DBCOL9" length="10" />
            </property>
            <property name="dbcolumn10" type="java.lang.Long">
                <column name="DBCOL10" precision="15" scale="0" />
            </property>
            <property name="dbcolumn11" type="java.lang.Long">
                <column name="DBCOL11" precision="15" scale="0" />
            </property>
            <property name="dbcolumn12" type="java.lang.Long">
                <column name="DBCOL12" precision="15" scale="0" />
            </property>
            <property name="dbcolumn13" type="string">
                <column name="DBCOL13" length="100" />
            </property>
            <property name="dbcolumn14" type="string">
                <column name="DBCOL14" length="40" />
            </property>
            <property name="dbcolumn15" type="string">
                <column name="DBCOL15" length="10" />
            </property>
            <property name="dbcolumn16" type="string">
                <column name="DBCOL16" length="30" />
            </property>
            <property name="dbcolumn17" type="java.lang.Long">
                <column name="DBCOL17" precision="15" scale="0" />
            </property>
            <property name="dbcolumn18" type="java.lang.Long">
                <column name="DBCOL18" precision="15" scale="0" />
            </property>
            <property name="dbcolumn19" type="string">
                <column name="DBCOL19" length="7" />
            </property>
            <property name="dbcolumn20" type="string">
                <column name="DBCOL20" length="7" />
            </property>
            <property name="dbcolumn21" type="string">
                <column name="DBCOL21" length="30" />
            </property>
            <property name="dbcolumn22" type="string">
                <column name="DBCOL22" length="30" />
            </property>
    </class>
</hibernate-mapping>



Factory setup and query code (from JUnit test case):

Code:

SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
boolean outcome = false;
      
int maxResults = 5;
      
try
{
          Configuration cfg = new Configuration();
          cfg.configure();
           
        sessionFactory = cfg.buildSessionFactory();
           
        session = sessionFactory.getCurrentSession();
        tx = session.beginTransaction();
           
        log.info("Creating criteria...");

   Criteria crit = session.createCriteria(MyTable.class);
          
   crit.add(Restrictions.eq("dbcolumn6", "value6"));
   crit.add(Restrictions.eq("dbcolumn1", "value1"));
   crit.add(Restrictions.like("dbcolumn3", "%" + "value3" + "%"));

        crit.setFirstResult(0);
        crit.setMaxResults(maxResults);
          
        log.info("Executing query...");
           
        long b = Calendar.getInstance().getTimeInMillis();
           
        List<MyTable> results =  crit.list();
           
        log.info("done in "+(Calendar.getInstance().getTimeInMillis()-b)+" ms");
           
        tx.commit();
           
        log.info("Results null? " + (results == null));
        log.info("Results empty? " + results.isEmpty());
           
        if(!results.isEmpty())
               log.info("First element null? " + (results.get(0) == null));
           
            outcome = (results != null && !(results.isEmpty()) && (results.get(0) != null));
}
       
catch (Exception e)
{
           tx.rollback();
           e.printStackTrace();
}
       
finally
{
           if(session != null && session.isOpen())
           {
              session.close();
              session = null;
           }
}

assertEquals(true,outcome);



Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 29, 2009 6:48 pm 
Newbie

Joined: Tue Jan 27, 2009 12:43 pm
Posts: 16
I found out what is causing the delay. The delay occurs when you prepare a statement that contains paramater markers and bound variables. If you run the statement with the values coded right into the SQL statement (i.e - you are not embedding ? for the arguments), then the statement runs quickly.

Can anybody elaborate on this overhead further? I am finding that even when I run the queries inside an application server, while utilizing a connection pool, the overhead seems to take place everytime. This tells me that the prepared statement is not being cached... At what point does a prepared statement get "destroyed".

Thank you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.