3

自分が抱えていた問題の回避策を見つけました。それが有効かどうかを知りたいのですが。これは、次のような問題と同様です。Grails Gorm:オブジェクトが未保存の一時インスタンスを参照している

私が2つのドメインオブジェクトを持っていると仮定しましょう(有罪を保護するために名前が変更されました)。

public class Shelf {
    String name
    Set<Book> books = [] as Set

    static hasMany = [books: Book]
}

public class Book {
    String title
    Shelf shelf
}

つまり、1つの棚には0から多数の本が含まれ、1つの本は1つの棚にしか置くことができません。

この棚はとても大きいです。そしてある時点で、80,000冊の本が含まれています。すべてDBにうまく保存されています。もちろん、新しい本の追加はどんどん遅くなっています。

これは次の方法で行われます。

  Book book1 = new Book("Awesome Title")
  existingShelf.addToBooks(book1)
  existingShelf.save(flush: true)      // super slow

これは遅いです。主に(私が推測する)GORMは他の80,000レコードを確認する必要があるためです。

だから私はスローポイントを回避するためにこれをしました。

  Book book2 = new Book("Awesome Title 2")
  book2.save(flush: true)

これにより、「オブジェクトが保存されていない一時インスタンスを参照している」ことがわかります。これは理にかなっていると思います。「シェルフ」の値は空です。

だから私は少し奇妙なことをしました:

  Book book3 = new Book("Awesome Title 3")
  book3.shelf = new Shelf()
  book3.shelf.id = <known/valid id here>
  book2.save(flush: true)

これは機能します。保存します。参照エラーはありません。これに依存するさらなるコードは...動作します。数分前に電話をかけ、数秒に短縮しました。しかし、それは簡単すぎるようです。どうにかしてGrailsの魔法を回避したと思います。そして、おそらくその過程で何かを壊した。

助言?説明?

4

1 に答える 1

5

はい、addTo*メソッドの使用は遅くなる可能性があります。生成されたSQLを見ると、その理由がわかります。次のことを行います。

new Book(title: "GORM Performance", shelf: grailsShelf).save()

より速くなり、技術的には何も問題はありません。データベースからコレクションを更新するまで、grailsS​​helf.booksのインスタンスには新しい本が含まれないことに注意してください。これは、addTo*メソッドが行うことの一部です。

サイドノート:

Set<Book> books = [] as Set

不要です。

于 2012-11-29T15:52:46.230 に答える