hibernate - Grails一对多选择ID的速度非常慢

标签 hibernate grails one-to-many

我在应用程序的某些部分遇到了非常慢的性能。
假设我有以下类(class)。

class Instrument{
 BigDecimal Value;
 String name;    
 InstrumentType type;
 InstrumentSubType sType;
 Country cls;
 Region reg;
 Sector sec;     
 static hasMany = [belongings: belongs] 
}

class DailyValuation{
   Instrument ins;
   Date valData;
   BigDecimal actualValue;
}

如果我要先插入新的DailyValuation,则需要获取该工具。
因此,在测量时间后,我得到:选择仪器仅需一秒钟
500行,插入需要30毫秒。

如果我在Mysql上进行常规查询,则选择时间少于10毫秒。我知道Hibernate具有一些懒惰和渴望的获取功能,因此:

有没有一种方法可以选择我需要的东西?就我而言,我只需要仪器ID。
我尝试了以下方法:
def nin = Instrument.executeQuery("select a.id from Instrument a where name='BONUS1'")
DailyValuation dVal = new DailyValuation(ins:nin); 

在观看了Hibernate Log SQL之后,我有一个选择可以获取ID,另一个可以获取整个乐器信息。

我应该如何进行才能尽快做到这一点?

非常感谢你的帮助。

最佳答案

使用集合的默认GORM映射将变慢,并且随着集合大小的增加而变慢。添加新的DailyValuation的典型模式是使用基于该域类的addToBelongings映射中的键生成的动态hasMany方法。默认情况下,该集合是延迟加载的,因此,如果尚未初始化它,则现在将完全填充它,然后将添加新实例(如果映射是双向的,则将其添加回父集)。保存父对象后,Hibernate将注意到有一个新实例并保存。但这是一种非常浪费的方法,根本不加载所有500个实例。

从技术上讲,这不是没有意义的-集合默认是Set,因此Hibernate需要加载所有其他实例以确保新实例是唯一的。而且,如果将其配置为List,则Hibernate需要所有其他实例来确保其位置正确,即使只是将其添加到末尾也是如此。

一种更直接,更高效的方法是不使用集合,而只是在保存之前在子级中设置父实例。从hasMany类中删除Instrument属性,然后在创建新的DailyValuation实例时,只需自行设置Instrument,例如

Instrument parent = ...
def dailyValuation = new DailyValuation(params)
dailyValuation.ins = parent
if (dailyValuation.save()) {
   ...
}
else {
   ...
}

几年前,我做了一个talk on this topic仍然很重要。

关于hibernate - Grails一对多选择ID的速度非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27631757/

相关文章:

spring - 服务器在Grails中以302响应时如何获取响应正文?

django - 发布一对多关系

java - YYYY-MM-DD HH 中的时间值 :MM:SS format

java - 如何实现通用分页

java - Eclipse 中的 Hibernate 工具 : Change in column values does not reflecting in the query result

grails - grails不会写入日志文件

json - 在 Grails 中将映射和属性列表作为 JSON 持久化

android - Realm 一对多关系不持久

forms - Symfony 2 使用一对多数据库关系的嵌入式表单

spring hibernate 和使用 ehcache 进行缓存