如何优化Grails中的选择属性?

Zac*_*ons 2 grails query-optimization grails-orm

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

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

这是控制器代码(scaffolded):

    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond Proposal.list(params), model:[proposalInstanceCount: Proposal.count()]
    }
Run Code Online (Sandbox Code Playgroud)

谢谢!

Bur*_*ith 5

我为这个场景编写了一个插件,请参阅http://grails.org/plugin/lazylob

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

class ProposalImage {
   byte[] image
}
Run Code Online (Sandbox Code Playgroud)

并从Proposal类引用它:

class Proposal {
   ProposalImage proposalImage
   // other properties
}
Run Code Online (Sandbox Code Playgroud)

由于默认情况下引用是惰性的,因此如果您专门引用它,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])
Run Code Online (Sandbox Code Playgroud)

这很方便,因为结果列表中的每个元素都是一个用属性名称键入的映射,因此它看起来与GSP中的真实Proposal实例相同.

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

def results = Proposal.withCriteria {
   projections {
      property 'prop1'
      property 'prop2'
   }
   maxResults(params.max as int)
   firstResult(params.offset as int)
}
Run Code Online (Sandbox Code Playgroud)

结果中的每个项都是一个Object []数组,数组中的每个元素都是属性的实际类型.您需要手动构建地图列表,例如

results = results.collect { result -> [prop1: result[0], prop2: result[1]] }
Run Code Online (Sandbox Code Playgroud)

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