1

我有一个 Grails 应用程序,它执行从许多表中提取的相当大的 createCriteria 查询。我注意到性能非常糟糕,并将其定位为我之后进行的对象操作,而不是 createCriteria 本身。我的查询成功地获取了我想要的所有原始对象,但是当我操作对象时,它正在为每个元素执行一个新查询。这是我的控制器代码的简化版本:

def hosts = Host.createCriteria().list(max: maxRows, offset: rowOffset) {
    // Lots of if statements for filters, etc.
}

def results = hosts?.collect{ [ cell: [
    it.hostname,
    it.type,
    it.status.toString(),
    it.env.toString(),
    it.supporter.person.toString()
    ...
 ]]}

我还有更多字段,包括对执行它们自己的查询以查找相关对象的方法的调用。所以我的问题是:如何将连接合并到原始查询中,这样我就不会为每一行执行大量额外的查询?目前查询约 700 行需要 2 分钟,这太长了。任何建议都会很棒!谢谢!

4

1 回答 1

3

使用标准获得的一个好处是您可以轻松地获取关联eagerly。因此,您在引用关联时不会遇到众所周知的 N+1 问题。

您没有提到标准中的逻辑,但我建议大约 700 行我肯定会选择这样的东西:

def hosts = Host.createCriteria().list(max: maxRows, offset: rowOffset) {
    ...
    //associations are eagerly fetched if a DSL like below 
    //is used in Criteria query
    supporter{
        person{

        }
    }

    someOtherAssoc{
        //Involve logic if required
        //eq('someOtherProperty', someOtherValue)
    }
}

如果你觉得定制一个 Criteria 很麻烦,那么你可以很好地回退到 HQL 并join fetch用于对关联的渴望索引。

我希望这肯定会将大约 700 条记录的周转时间减少到不到 5 秒。

于 2013-11-05T03:07:14.230 回答