Использование ORM, такого как Hibernate, для этой задачи всегда будет медленнее, чем использование db в вашей версии прототипа, которая напрямую использует слой JDBC. Посмотрим, что происходит:
List<Presenter> result = session.createQuery("from Presenter p WHERE p.presenter_name in :names", Presenter.class)
.setParameterList("names", names)
.getResultList();
После того, как запрос проанализирован, объекты разрешены, а размер names
определяет количество параметров, в которые он будет расширен (?,?,?...)
.
Затем запрос отправляется, и как только результаты поступают, у каждой из них создается две копии. Тот, который вам дан в списке результатов, и тот, который хранится внутри, чтобы проверить изменения.
for (Presenter presenter : result) {
int presenter_id = presenter.getPresenter_id();
List<Programme> programmes = session
.createQuery("from programme prog WHERE prog.presenter_origin_id = :pres_orig_id", Programme.class)
.setParameter("pres_orig_id", presenter_id)
.getResultList();
Здесь у нас снова происходит то же самое, но на самом деле все немного хуже. Вместо повторного использования запроса вы создаете новый в каждом цикле и отбрасываете его после.
То же самое происходит во вложенном цикле.
Также, если Presenter.getPresenter_id () возвращает объект Integer
вместо примитива int
, вы делаете ненужную распаковку, а затем перепаковываете вызов .setParameter("pres_orig_id", presenter_id)
. Измените его на Integer presenter_id
, если метод возвращает объект Integer. Но если это примитив int
, то в этом нет необходимости, но это не повредит, поскольку единственное использование передается как Объект. Вы даже можете использовать его непосредственно в setParameter
.
Таким образом, в целом, когда вы берете вызовы createQuery из цикла, вы получаете это.
@Override
public DJAllProgrammes getAllProgrammesFromDJ(Collection<String> names) {
DJAllProgrammes djAllProgrammes = new DJAllProgrammes();
session.beginTransaction();
List<Presenter> result = session.createQuery("from Presenter p WHERE p.presenter_name in :names", Presenter.class)
.setParameterList("names", names)
.getResultList();
TypedQuery<Programme> progByPresenterOrigin = session
.createQuery("from programme prog WHERE prog.presenter_origin_id = :pres_orig_id", Programme.class);
TypedQuery<Track> trackByProgrammeId = session
.createQuery("FROM track t WHERE t.programme.programme_id in :progIds", Track.class)
for (Presenter presenter : result) {
List<Programme> programmes = progByPresenterOrigin
.setParameter("pres_orig_id", presenter.getPresenter_id())
.getResultList();
for (Programme programme : programmes) {
//this is the critical performance death zone
List<Track> tracksOnThisProgramme = trackByProgrammeId
.setParameter("progIds", programme.getProgramme_id())
.getResultList();
djAllProgrammes.addProgramme(new ProgrammeData(presenter.getPresenter_name(), programme.getDate(), tracksOnThisProgramme));
}
}
session.getTransaction().commit();
return djAllProgrammes;
}