производительность выполнения запроса openjpa

У меня есть веб-приложение для отдыха с фреймворком cxf 3.0.1 и openjpa 2.3.0. Веб.xml:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="thePU" transaction-type="RESOURCE_LOCAL">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <class>xz.Partner</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>

            <property name="openjpa.DataCache" value="true(
                    Types=
                        /*selected classes*/
                    EvictionSchedule='0 0 * * *')"/>

            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://some.remote.rds.amazonaws.com:3306/XZdb?zeroDateTimeBehavior=convertToNull"/>
            <property name="javax.persistence.jdbc.user" value="XXX"/>
            <property name="javax.persistence.jdbc.password" value="XXX"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.validation.mode" value="NONE"/>
            <property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
            <property name="openjpa.ConnectionFactoryProperties" 
                      value="PrettyPrint=true, PrintParameters=true"/>      
            <property name="openjpa.Compatibility" value="default(flushBeforeDetach=false)"/>
        </properties>
    </persistence-unit>
</persistence>
5.xsd"> <display-name>Mobile app rest services</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/cxf-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> </web-app>

постоянство.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="thePU" transaction-type="RESOURCE_LOCAL">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <class>xz.Partner</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>

            <property name="openjpa.DataCache" value="true(
                    Types=
                        /*selected classes*/
                    EvictionSchedule='0 0 * * *')"/>

            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://some.remote.rds.amazonaws.com:3306/XZdb?zeroDateTimeBehavior=convertToNull"/>
            <property name="javax.persistence.jdbc.user" value="XXX"/>
            <property name="javax.persistence.jdbc.password" value="XXX"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.validation.mode" value="NONE"/>
            <property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
            <property name="openjpa.ConnectionFactoryProperties" 
                      value="PrettyPrint=true, PrintParameters=true"/>      
            <property name="openjpa.Compatibility" value="default(flushBeforeDetach=false)"/>
        </properties>
    </persistence-unit>
</persistence>

Затем я рассчитал время выполнения некоторых запросов с System.currentTimeMillis() до и после процесса выполнения, и это дает мне довольно разные результаты из журнала трассировки openjpa.

2333  thePU  TRACE  [qtp1769466090-14] openjpa.jdbc.SQL - <t 2143135982, conn 1825478533> [164 ms] spent
2015-06-15[INFO]xz.orm.dao.impl.util.PerfMeasureUtil stop: :: exec query time: 824ms

Затрачено [164 мс] против время выполнения запроса: 824 мс

Это собственный запрос, объединяющий около 4 таблиц. Я сам управляю временем жизни entityManager - создаю в начале и закрываю в конце запроса.

/**
 * Enables the derived classes to execute read only operation using the entityManager
 *
 * @param <T>
 * @param operation
 * @return
 */
protected <T> T executeNonTransactionOperation(SimpleOperation<T> operation) {
    try {
        EntityManager entityManager = PersistenceHelper.getEntityManager();

        T result = operation.execute(entityManager);

        return result;
    } catch (Exception e) {
        //TODO: throw our custom exception?
        throw e;
    } finally {
        PersistenceHelper.closeEntityManager();
    }
}

/**
 * Enables the derived classes to execute operation (inside transaction) using the entityManager
 *
 * @param <T>
 * @param operation
 * @return
 */
protected <T> T executeTransactionOperation(SimpleOperation<T> operation) {
    try {
        EntityManager entityManager = PersistenceHelper.getEntityManager();

        PersistenceHelper.beginTransaction();
        T result = operation.execute(entityManager);
        PersistenceHelper.commit();

        return result;
    } catch (Exception e) {
        PersistenceHelper.rollback();
        //TODO: throw our custom exception?
        throw e;
    } finally {
        PersistenceHelper.closeEntityManager();
    }
}

Почему такая разница, если openjpa заявляет, что выполняется так быстро?


person Zavael    schedule 15.06.2015    source источник
comment
Если это относится к MySQL, пожалуйста, покажите нам запросы. Если не по теме, удалите тег.   -  person Rick James    schedule 16.06.2015


Ответы (1)


Проблема в том, что вы измеряете две разные вещи. 164 ms — это время, которое база данных потратила на выполнение запроса. Я подозреваю, что 824 ms, который вы измерили, - это выполнение запроса + создание экземпляров ваших объектов Entity.

person Rick    schedule 15.06.2015
comment
да, вы правы, я думал об этом, но мне показалось, что для создания объектов Java слишком много времени - person Zavael; 16.06.2015
comment
Это довольно много времени, так что стоит копаться. Опять же, я подозреваю, что вы можете измерять больше, чем просто создание экземпляра объекта/обработку набора результатов. Лучше всего было бы подключить профилировщик, чтобы увидеть, на что тратится время. - person Rick; 16.06.2015