使用连接提高Grails CreateCriteria查询速度

时间:2013-11-05 02:58:19

标签: mysql sql performance hibernate grails

我有一个Grails应用程序,可以从许多表中执行相当大的createCriteria查询。我注意到性能非常糟糕,并且已经确定了我之后做的Object操作,而不是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分钟,这太长了。任何建议都会很棒!谢谢!

1 个答案:

答案 0 :(得分: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秒。