java - 为什么 Hibernate 会生成约 500 个 SQL 查询?

标签 java mysql hibernate

当尝试在遗留项目中优化 Hibernate 4.2 生成的 MySQ 慢查询时,我发现下面的代码生成了近 500 个 SQL 查询(有很多重复项):

class MyDAO {
    public List<Message> findMessages() {
        Session session = MyHibernateUtils.openSession();

        String queryStr = "SELECT DISTINCT m FROM Message m "
                + " LEFT JOIN fetch m.types types "
                + " LEFT JOIN fetch m.mainType mainType "
                + " LEFT JOIN fetch m.place place "
                + " LEFT JOIN fetch m.building building "
                + " LEFT JOIN fetch m.city city "
                + " LEFT JOIN fetch m.kind kind "
                + " LEFT JOIN fetch m.domain domain "
                + " LEFT JOIN fetch m.action action "
                + " LEFT JOIN fetch m.customParameterA customParameterA "
                + " LEFT JOIN fetch m.customParameterB customParameterB "
                + " LEFT JOIN fetch m.scheduleEvents scheduleEvents "
                + " LEFT JOIN fetch m.comments comments "
                + " LEFT JOIN fetch m.messageLastActivities messageLastActivities "
                + " LEFT JOIN fetch m.customListA customListA "
                + " LEFT JOIN fetch m.childEvents childEvents "
                + " LEFT JOIN fetch m.parentEvent parentEvent "
                + " WHERE ...";

        List<Message> messages;
        try {
            session.getTransaction().begin();

            Query query = session.createQuery(queryStr);
            query.setTimeout(10);

            messages = query.list();
            session.getTransaction().commit();
        } catch (RuntimeException e) {
            session.getTransaction().rollback();
            throw e;
        } finally {
            session.close();
        }

        return messages;
    }
}

如何避免出现如此多的 SQL 查询?

我不知道这是否有帮助,但实体之间有许多 onyToMany 和 ManyToMany 关系。

感谢您的帮助。

最佳答案

您应该检查 hibernate 生成的查询,以查看哪个表被频繁访问。

您还必须加入与您的相关实体相关的提取实体,请参见此处:

Hibernate is doing multiple select requests instead one (using join fetch)

我个人更喜欢使用带注释的 @BatchSize() 进行延迟加载,以保持惰性查询计数较小。只需使用 Batch-Size 2 即可将查询数量减少一半。

另请查看 @Cache 注解,它可以显着减少查询次数。 (只考虑所有几乎静态的东西,例如城市/建筑物/类型/域等)

关于java - 为什么 Hibernate 会生成约 500 个 SQL 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46609189/

相关文章:

java - 为什么我不能导入 java.util.concurrent.ConcurrentSkipListMap

java - 避免多个 if/else 条件

java - 更改 Dropwizard 默认端口

mysql - 多个服务器上的常量

mysql - 将 WHERE 子句中的 SUBQUERY 更改为 NORMAL JOIN

java - 如何通过连接集合限制结果集

java - Java 中具有可能空值的 CharSequence 和 String 对象之间的相等性检查

php - 如何显示与其他数据对应的数据 MySQL PHP

hibernate - 如何克服Grails Service中的StaleObjectStateException

java - 获取 JPA 和 Hibernate 继承树中的鉴别器值列表