我编写了一个应用程序,可以抓取互联网广播播放列表,然后将它们保存到数据库中。为了了解 hibernate,我将应用程序迁移为使用 hibernate,但与其他尝试相比,在执行 SELECT ... WHERE 查找时,我发现性能大幅下降。与我的(可能是可怕的)相比,相同的过程(获取大约 17,000 个轨道,按播放程序和播放者分组)在我的 python sqlite 原型(prototype)中花费了 150 毫秒,而使用 apache db utils 的初始 java 版本花费了大约 250 毫秒。 ) hibernate 版本大约需要1100ms。
@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();
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();
for (Programme programme : programmes) {
//this is the critical performance death zone
List<Track> tracksOnThisProgramme = session
.createQuery("FROM track t WHERE t.programme.programme_id in :progIds", Track.class)
.setParameter("progIds", programme.getProgramme_id())
.getResultList();
djAllProgrammes.addProgramme(new ProgrammeData(presenter.getPresenter_name(), programme.getDate(), tracksOnThisProgramme));
}
}
session.getTransaction().commit();
return djAllProgrammes;
}
调试信息:
信息: session 指标
{
33339 nanoseconds spent acquiring 1 JDBC connections;
71991 nanoseconds spent releasing 1 JDBC connections;
12938819 nanoseconds spent preparing 258 JDBC statements;
88949720 nanoseconds spent executing 258 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
4671332 nanoseconds spent executing 1 flushes (flushing a total of 9130 entities and 0 collections);
599862735 nanoseconds spent executing 258 partial-flushes (flushing a total of 1079473 entities and 1079473 collections)
}
在互联网上浏览时,我看到了一个基于事务中太多实体“使用分页和较小批量增量”的建议 - 我可以找到有关什么是分页的信息,但不太了解“使用较小批量增量”的信息意思是“
我有点陷入困境,这个应用程序具有良好的性能,使用 Apache DB Utils(一个轻量级 jdbc 包装器)做基本上相同的事情,而且我很无知,我什至不知道要搜索什么以加快速度。帮帮兄弟吗?
这里还使用了bean(持久性实体...?)https://pastebin.com/pSQ3iGK2
最佳答案
一般来说:OR-Mapper 允许您对与另一个实体相关的实体进行建模。 我在您的代码中看到了一些 1:N 关系,演示者有很多程序。
类名“Programme”可能是第一个错误,因为它是复数。更好地使用“Programm”并在“Presenter”类中建模 @OneToMany 关系。
当您这样做时,您只需触发一个 hibernate 查询。找到的“演示者”类型实体将包含“节目”列表/集。迭代实体并将它们转换为返回值“DJAllProgrammes”,该返回值应仅包含普通值 (dto),而不包含对实体的引用。 IE。将实体映射到 dto。
关于java - Hibernate (PostgreSQL) 与 jdbc 相比,外键上的慢速选择查询 WHERE 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54022425/