Обратите внимание, что если вы хотите сравнить две концепции, вы должны попытаться изолировать основную функцию и избавиться от других факторов, которые могут повлиять на результат.
Чтобы увидеть , если JDB C запрос и собственный запрос JPA отличаются по поведению Я бы предложил следующий сценарий:
Вот простая настройка для проверки исполнения. Таблица содержит 50 строк для каждого GRP_ID
, что приводит к получению 50K строк для 1000 ключей (см. Ниже скрипт для настройки таблицы)
List params = (13001L..14000L)
def query = session.createNativeQuery("select * from tab where grp_id in (:paramsList) ")
query.setFetchSize(2000)
query.setParameterList("paramsList", params);
result = query.getResultList();
Пример выполнения показывает этот результат
got 50000 rows in 1.388 seconds
Итак, я думаю, что нет необходимости повторять тест с простым JDB C, вы увидите сопоставимый результат.
Что более интересно, повторить прогон и удалите строку
query.setFetchSize(2000)
, которая эффективно сбросит размер выборки к значению по умолчанию (в моем случае - 20), результат для тех же данных будет
got 50000 rows in 1 minutes, 0.903 seconds
1) Таким образом, размер выборки является наиболее подходящим объяснением наблюдаемого поведения . Важно убедиться, что диск JDB C получил правильное значение и использует его - если вы сомневаетесь, вы должны использовать трассировку 10046, чтобы увидеть, какой размер выборки использует базу данных. Но для меня вышеупомянутое утверждение сработало отлично.
2) Нет существенной разницы между собственным запросом JPA и написанным вручную JDB C execute + выборкой подготовленного оператора , который бы объясните свое наблюдение Оба выполняют выполнение оператора в базе данных , за которым следует число выборок - количество зависит от используемого размера выборки
3) Конечно, представление также может иметь влияние, но это будет разница в запросе - не между JDB C v. JPA .
4) Вы не упомянули об этом, поэтому я не буду вдаваться в подробности и предполагаю, что ваше представление не содержит столбцов CLOB
, Это, конечно, может сыграть свою роль.
5) Последний пункт в вашем упоминании два запроса - используете ли вы два независимых запроса или один запрос с OR
объединены в списке? Вы не предоставляете подробности, поэтому это трудно комментировать. В любом случае два независимых запроса не должны иметь никакого влияния.
Сказав это одно предупреждение.
Ограничение подсчета списка IN имеет свое назначение. Для и объявления Ho c script допустимо использовать большой выбор списка IN, но для регулярного выполнения запроса это может быть проблема синтаксического анализа . Почему?
Вы используете переменные связывания, чтобы иметь возможность рассматривать следующие очереди как одно утверждение (которое анализируется только один раз)
select * from tab where ID = 1
select * from tab where ID = 2
, что приводит к
select * from tab where ID = ?
Но после двух запросов (с разной длиной списка IN) остается разным и должен подвергаться дополнительному анализу
select * from tab where ID in ( ? )
select * from tab where ID in ( ?, ? )
Так что повторите, если для вашей цели с 30K строк + Hibernate является лучшим вариантом
Hibernate был разработан, чтобы элегантно получить представление о необходимости с использованием SQL, который большинством разработчиков считают круто думать (в отличие от большинства сотрудников БД, имеющих противоположное значение;).
Эта концепция работает отлично, чем проще случай использования. С другой стороны, для пакетной обработки иногда лучше подойти к нему напрямую с SQL
Данные испытаний
create table tab as
select
rownum id,
trunc(rownum / 50) +1 grp_id,
rpad('x',100,'y') pad
from dual connect by level <= 1000000;
create index idx on tab(grp_id);