Jpa , Hibernate 选择查询优化

Posted

技术标签:

【中文标题】Jpa , Hibernate 选择查询优化【英文标题】:Jpa , Hibernate select query optimization 【发布时间】:2013-05-23 10:57:34 【问题描述】:

我是 JPa / Hibernate 的新手。 我们在我们的应用程序中使用 JPA 和休眠。 目前我观察到对带有条件的表执行选择查询,休眠对每一行执行选择查询。

所以我的问题是,hibernate 如何对表执行搜索并检索记录?

我有一个需要找到活跃用户的场景 并在活动用户列表上执行文件管理器,例如最近登录的用户,最受欢迎的用户(基于某些标准) 我有 100 个活跃用户,其中 最近有 20 个用户登录。 20 个用户最受欢迎。

如果我必须从数据库中获取记录, 当我查询活动用户时,休眠执行 100 次选择操作。(使用表扫描)

和 如果我对最近和最受欢迎的用户执行 2 个单独的查询 hibernate 将执行 20 + 20 = 40 次选择操作。 (但有 2 次表扫描)

那么hibernate是如何从数据库中获取记录的呢? 如果我与 jdbc 进行比较,我会说通过获取活动音高并对其执行过滤器,我将进行 1 次时间表扫描。

但是使用休眠它执行更多的选择操作,当我为最近和最受欢迎的用户进行个人选择时,它查询的选择更少,即使我进行 2 次时间表扫描!

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "fk_profile_id", referencedColumnName = "pk_id")
private Profile Profile;

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "investmentPitch", targetEntity = InvestmentType.class, orphanRemoval = true)
private List<InvestmentType> investmentType;

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "investmentPitch", targetEntity = TabDetail.class, orphanRemoval = true)
private List<TabDetail> TabDetail;

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "investmentPitch", targetEntity = Address.class, orphanRemoval = true)
private List<Address> Address;

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
@JoinTable(name = "pitch_sector", joinColumns =  @JoinColumn(name = "fk_id", nullable = false, updatable = false) , inverseJoinColumns =  @JoinColumn(name = "fk_sector_id", nullable = false, updatable = false) )
private List<SectorMaster> sectors;

【问题讨论】:

能否请您发布您的映射和类。 Hibernate 肯定不会通过一次选择来检索每条记录。加载记录列表后,必须为每条记录加载一些映射(例如一对多)。 我已经更新了我的映射对象......它主要有 oneToMany 和 ManyToMany 关系......当我对上述表(investmentPitch)执行选择时,它会使用选择查询查询每条记录 FetchType.EAGER 会在初始化时加载东西,一般来说,这不是你想要做的。 您能测试并从配置文件中删除 FetchType.EAGER 吗?我认为这会触发每个加载的用户选择加载配置文件。 感谢您的回复...实际上我希望每次获取用户时都加载配置文件,但我的实际问题是:当我在表上执行选择时,我希望通过调用返回列表“query.getResultList()”所以我期待一个选择查询,但是休眠对单个记录执行选择?为什么会这样? 【参考方案1】:

FetchType.EAGER 导致休眠在加载用户后直接加载配置文件。这会触发每个用户的选择。

您可以将其更改为 LAZY。然后只有在您第一次访问配置文件对象时才会触发选择。如果您必须访问每个选定用户的配置文件,这也会导致每个用户都进行选择。为避免这种情况,您可以在一次选择中与用户一起预加载配置文件。有关这方面的详细信息,请参阅以下链接:http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html#querycriteria-dynamicfetching 和 http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-fetching

【讨论】:

以上是关于Jpa , Hibernate 选择查询优化的主要内容,如果未能解决你的问题,请参考以下文章

即使使用 @Fetch(FetchMode.JOIN),JPA + Hibernate 也会出现太多查询问题

[Hibernate Search] 基础查询

Spring Hibernate JPA 联表查询 复杂查询

使用 JPA 原生查询时是不是必须选择所有实体属性?

Hibernate 查询方式JPA查询方式

Spring Hibernate JPA 联表查询 复杂查询