Долгое время выборки данных из OracleDB с использованием Eclipselink - PullRequest
0 голосов
/ 03 мая 2020

В моем приложении я использую Eclipselink в качестве ORM для OracleDB и столкнулся с проблемой производительности.

Я выполняю код, подобный следующему:

entityManager
 .createNamedQuery(RoleToPermissionEntity.FIND_BY_APPLICATION_ROLE, RoleToPermissionEntity.class)
 .setParameter(RoleToPermissionEntity.APPLICATION_ROLES_QUERY_PARAM, applicationRoles)
 .getResultList();

с именованным запросом:

SELECT mapping 
FROM RoleToPermissionEntity mapping 
WHERE mapping.applicationRole IN :applicationRoles 
ORDER BY mapping.id

Менеджер сущностей установлен на @PersistenceContext.

Для 3 заданных ролей приложения приложение получает 123 строки (из 393), 9 столбцов каждая (2 метки времени с часовым поясом, 3 числа, 4 короткие varchars).

Я проверил время выполнения как разницу между System.nanoTime() до и после выполнения данного кода. Это около 550 мс, независимо от того, выполняется оно 1-й раз или 10-й подряд. И я предполагаю, что это должно быть намного быстрее.

Моим первым предположением была проблема с запросом, поэтому я проверил логи Eclipselink. Выполненный запрос:

SELECT *all_columns* 
FROM *table_name* 
WHERE (APPLICATION_ROLE IN (?,?,?)) ORDER BY ID
    bind => [3_application_roles]

Выглядит нормально для меня. Я пытался выполнить его как собственный запрос, но результат тот же. Я пробовал также другие запросы, такие как SELECT * FROM table_name, но время все еще составляет около 500-600 мс.

Я хотел провести некоторое сравнение для этого времени, поэтому я создал соединение с базой данных вручную и выполнил запрос, например:

Class.forName("oracle.jdbc.driver.OracleDriver");
connection = DriverManager.getConnection(database_args);
Statement statement = connection.createStatement();
statement.executeQuery(query);

Я выполнил это несколько раз, сначала (когда было установлено соединение) это заняло довольно много времени, но затем заняло около 50-60 мс.

Вторым моим предположением была проблема с пулом соединений. Я попытался найти что-то в документации по Eclipselink и заметил только, что должны быть установлены параметры:

<property name="eclipselink.connection-pool.default.initial" value="1"/>
<property name="eclipselink.connection-pool.default.min" value="16"/>
<property name="eclipselink.connection-pool.default.max" value="16"/>

. Они есть, но проблема все еще существует.

Содержание моей настойчивости. xml:

<persistence>
<persistence-unit name=unit transaction-type="JTA">
        <jta-data-source>datasource</jta-data-source>

        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <!-- cache needs to be deactivated for multiple pods -->
        <!-- https://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching -->
        <shared-cache-mode>NONE</shared-cache-mode>

        <properties>
            <property name="eclipselink.logging.level" value="FINE"/>
            <property name="eclipselink.logging.level.sql" value="FINE"/>
            <property name="eclipselink.logging.parameters" value="true"/>
            <!--<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>-->
            <property name="eclipselink.weaving" value="false"/>
            <property name="eclipselink.target-database"
                      value="org.eclipse.persistence.platform.database.oracle.Oracle12Platform"/>
            <property name="eclipselink.connection-pool.default.initial" value="1"/>
            <property name="eclipselink.connection-pool.default.min" value="16"/>
            <property name="eclipselink.connection-pool.default.max" value="16"/>
        </properties>

    </persistence-unit>
</persistence>

Что я могу сделать, чтобы исправить это поведение?

1 Ответ

0 голосов
/ 05 мая 2020

Через несколько часов я обнаружил проблему. Размер выборки по умолчанию OJDB C равен 10, поэтому с увеличением количества строк время выборки увеличивается очень быстро.

Что странно: это была моя первая идея, поэтому я попытался установить <property name="eclipselink.jdbc.fetch-size" value="100"/> в persistence.xml. Это не сработало, поэтому я перешел к другим решениям. Сегодня я установил его на один запрос по query.setHint("eclipselink.jdbc.fetch-size", 100), и он работает.

...