如何优化Grails中的select属性?

如何优化Grails中的select属性?,grails,query-optimization,gorm,Grails,Query Optimization,Gorm,我有一个在生产中使用的应用程序,当用户进入建议索引页面时,需要很长时间,有时会超时。我已经将问题缩小为一个SQL语句,它选择所有的提议对象。问题是Proposal对象在内存中存储了许多图像(字节[]),而索引页中没有使用这些图像。这些图像是巨大的,因此造成了问题 在Grails中优化此查询的不同方法有哪些,可以删除该页面上不需要的属性,或者只添加GSP中的属性 以下是控制器代码(脚手架): 谢谢 我为这个场景编写了一个插件,请参见 另一种选择是将域类重构为两个。将图像数据放入新的域类: clas

我有一个在生产中使用的应用程序,当用户进入建议索引页面时,需要很长时间,有时会超时。我已经将问题缩小为一个SQL语句,它选择所有的提议对象。问题是Proposal对象在内存中存储了许多图像(字节[]),而索引页中没有使用这些图像。这些图像是巨大的,因此造成了问题

在Grails中优化此查询的不同方法有哪些,可以删除该页面上不需要的属性,或者只添加GSP中的属性

以下是控制器代码(脚手架):


谢谢

我为这个场景编写了一个插件,请参见

另一种选择是将域类重构为两个。将图像数据放入新的域类:

class ProposalImage {
   byte[] image
}
并从建议类中引用:

class Proposal {
   ProposalImage proposalImage
   // other properties
}
由于默认情况下引用是惰性的,因此GORM仅在您特别引用新域类时才会从该域类加载图像数据

编辑(使用子选择方法更新):

还可以使用自定义查询选择属性的子集。最方便的方法可能是在HQL查询中使用“选择新映射”:

def results = Proposal.executeQuery(
   'select new map(prop1 as prop1, prop2 as prop2) from Proposal',
   [max:params.max as int, params.offset as int])
这很方便,因为结果列表中的每个元素都是一个用属性名键入的映射,因此它看起来与GSP中的真实提案实例相同

如果您更喜欢条件查询,另一个选项是使用投影来限制返回的属性:

def results = Proposal.withCriteria {
   projections {
      property 'prop1'
      property 'prop2'
   }
   maxResults(params.max as int)
   firstResult(params.offset as int)
}
结果中的每个项都是Object[]数组,数组中的每个元素都是属性的实际类型。您需要手动创建地图列表,例如

results = results.collect { result -> [prop1: result[0], prop2: result[1]] }

此外,您可以通过查找持久性属性的所有名称并排除希望避免的名称来自动执行此操作:
def propNames=grailsApplication.getDomainClass(Proposal.name).persistentProperties*.name

谢谢@burt,但这两种方法都会更改模型。有没有其他方法可以做到这一点而不改变模型?(我不反对更改模型,我只想查看所有选项)也许应该有一个增强功能,只将GSP中列出的属性包含在所选属性中?再次感谢@burt,我喜欢第三种和第四种方法,但有一件事让我感到困扰,那就是我必须明确我想要的属性。如果我更改GSP而忘记更改控制器,则可能会导致问题。我希望grails能够自动知道这一点。我想我可能可以通过反射来实现,但它可能是列表加载中的一个选项。您认为增强请求是个好主意吗?我添加了一些代码,可以让您找到所有的持久属性。这样,您就可以确保,如果类发生更改,您仍然会包含GSP所期望的所有内容。@burt关于域类持久属性列表的详细信息。非常感谢。
results = results.collect { result -> [prop1: result[0], prop2: result[1]] }