1

多くのテーブルからプルする、かなり巨大な createCriteria クエリを実行する Grails アプリケーションがあります。パフォーマンスがかなりひどいことに気付き、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

基準を使用して得られる利点の 1 つは、関連付けを簡単に取得できることです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)
    }
}

基準を調整するのが面倒だと感じた場合は、HQL にフォールバックしてjoin fetch、関連付けの熱心なインデックス作成に使用できます。

これにより、〜700レコードのターンアラウンドタイムが5秒未満に確実に短縮されることを願っています.

于 2013-11-05T03:07:14.230 に答える