我写了一个应用程序,可以抓取互联网广播播放列表,然后将其保存到数据库中。为了了解休眠,我将应用程序迁移为使用休眠,但是与其他尝试相比,在执行SELECT ... WHERE查找时,我发现性能下降很大。在我的python sqlite原型中,相同的过程(获取大约17,000个曲目(按播放它们的程序和播放它们的人分组))花费了150毫秒,而使用apache db utils的初始Java版本花费了约250毫秒,与我的过程相比(可能太恐怖了) )的休眠版本,大约需要1100毫秒。

@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;
}


调试信息:

INFO:会话指标

{
    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包装器)可以完成基本相同的性能,而且我非常无知,我什至不知道要搜索什么来加快速度起来。帮兄弟出去吗

还在这里https://pastebin.com/pSQ3iGK2使用的bean(持久性实体...?)

最佳答案

一般说来:OR-Mapper允许您相对于另一个实体建模。
我看到您的代码中有许多程序的演示者存在一些1:N关系。

类名“ Programme”可能是第一个错误,因为它是复数形式。最好在类“ Presenter”中使用“ Programm”并为@OneToMany关系建模。

这样做时,您只需触发一个休眠查询。找到的“ Presenter”类型的实体将包含“ Programm”的列表/集。遍历实体并将其转换为返回值'DJAllProgrammes',该返回值应仅包含纯值(dto),而不应包含对实体的引用。即将实体映射到dto。

09-30 17:08