0

Grails アプリケーションでは、デフォルトで遅延している関係があります。

class Author{
    String name
    static mapping = {
         books lazy:false
    }
}

著者を取得する基準 API クエリがあります。クエリを実行すると

Author.createCriteria().list{
    eq("name", "John")
}

私は著者ごとに N+1 個のサブセレクトを持っています。

私の 2 番目のアプローチは、次のように本を熱心にフェッチすることです。

Author.createCriteria().list{
    eq("name", "John")
    fetchMode("books", FetchMode.JOIN)
}

この場合、N+1 選択の問題は発生しませんが、JOIN クエリがあります。

パフォーマンスと最適化の点でどちらのアプローチが優れていますか?

4

1 に答える 1

0

質問の最初の行ではeagerなく、デフォルトで意味していたと思います。lazy

注意
点 関連付けが条件クエリに含まれている場合、関連付けはデフォルトで熱心にフェッチされます。

あなたの場合、のマッピングは必要ありませbooks lazy:falseAuthor最適化
に関しては、以下のアプローチを保証します。

class Author {
    String name
    static hasMany = [books: Book]
    static mapping = {
         //books lazy:false (DO NOT NEED)
    }
}

class Book {
    String bookName
    //set belongsTo if you need bi-directional one-many
    //books gets cascade deleted when author is deleted
    //static belongsTo = [author: Author]
}

//Bootstrap
def author1 = new Author(name: "Dan Brown")
def book1 = new Book(bookName: "Da Vinci Code")
def book2 = new Book(bookName: "Angels And Demons")
def book3 = new Book(bookName: "Inferno")

[book1, book2, book3].each {author1.addToBooks(it)}
author1.save(flush: true, failOnError: true)

//Criteria
Author.createCriteria().list{
    eq("name", "Dan Brown")
    books{
       //books are eagerly fetched by default using inner join. No need to specify FetchMode.
    }
}

パフォーマンスの観点から、20000 のブログを書いた各著者がいる場合 (本をブログに置き換えます)、上記のアプローチは使用しません。著者のために 20000 のブログを積極的にフェッチnすると、パフォーマンスが低下します。この場合、遅延フェッチ (N + 1) ルートを使用し、要件に従ってブログを除外しようとします。以下のようなもの:

def author = Author.findByName("Dan Brown")
def books = author.books
//Assume you have a field publishedYear in Book
def booksReleasedIn2013 = author.books.findAll{it.publishedYear == 2013} 
def booksReleasedBefore2013 = author.books.findAll{it.publishedYear < 2013} 

assert "Inferno" in booksReleasedIn2013*.bookName
assert "Angels And Demons" in booksReleasedBefore2013*.bookName

そのような(ブログのケース)ケースがない場合は、上記の例を最適化パフォーマンスの両方に使用します。

于 2013-06-08T21:27:21.970 に答える