java - Hibernate (PostgreSQL) 与 jdbc 相比,外键上的慢速选择查询 WHERE 子句

标签 java sql postgresql hibernate

我编写了一个应用程序,可以抓取互联网广播播放列表,然后将它们保存到数据库中。为了了解 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/

相关文章:

mysql - SQL查询比较两个表

java - 如何在准备好的语句java中插入大整数

java - 在二维数组中添加对象大小未知的JAVA列表

java - 使用分隔值对数组进行排序

sql - 如何在select语句中调用表值函数?

php - Laravel SQL 按 WHERE IN Group By 更新行

database - postgresql 是否跟踪它进行的全表扫描?

在相邻表中定义顺序的 SQL 查询表

java - 获取 Facebook 通知 API 3.0

java - JUnit 中时区的正则表达式匹配