У меня есть таблица T_LOG, в которой несколько миллионов строк. Hibernate 3.6.10.Final
с использованием Detached Criteria создает неэффективный SQL-запрос, который сильно влияет на производительность.
Упрощенный образец:
select temp.* from ( select row_number() over(order by a.dateTime asc) as rownumber, a.dateTime, a.*
from T_LOG a order by a.dateTime asc) as temp where rownumber <= 75;
Проблема в order by a.dateTime asc
(2), которая является избыточной, потому что вся работа выполняется по первому пункту row_number() over(order by a.dateTime asc)
(1).
Это дополнительное второе предложение order by
дает примерно в 1000 раз худший результат, чем то же самое без него.
Например, для вышеприведенного оператора требуется более 10 минут в строках по 25 миллионов, но это упрощенный оператор:
select temp.* from ( select row_number() over(order by a.dateTime asc) as
rownumber, a.dateTime, a.* from T_LOG a) as temp where rownumber <= 75;
Занимает всего 0,1 секунды. Набор результатов такой же. Столбец dateTime
является индексированным неуникальным индексом.
В Java отдельный критерий (упрощенный) выглядит следующим образом:
DetachedCriteria crit = DetachedCriteria.forClass(Log.class);
...
crit.addOrder(org.hibernate.criterion.Order.asc("dateTime"));
// Used for pagination
List<Log> logs = logRepository.findByCriteria(crit, from, count);
Как уменьшить оператор SQL в отдельных критериях, чтобы избежать влияния на производительность?
Образец хорошей стоимости:
А стоимость кровати: