私は grails 2.2.2 と mysql データベースを使用しています。テーブルには 800 のレコードがあります (時間の経過とともに増加します)。いくつかの計算に基づいて、特定の列の値を新しい値に更新する必要があります。パフォーマンスに影響を与えない方法を提案してください。
3 に答える
そのような場合、私は通常、1000 個程度のオブジェクトごとにセッションをフラッシュしています。
SomeDomain.list().eachWithIndex{ obj, ix ->
obj.doSomeCalc()
obj.save flush:0 == ix % 1000
}
次のリンクを使用して、複数のインスタンスで使用Model.withTransaction()
するときにバッチ更新を可能にする方法を使用してこれを解決しました: http://www.tothenew.com/blog/batch-processing-in-grails/Model.save()
例えば:
List batch = []
(0..1000).each {
Model model = new Model(...)
batch.add(model)
Model.withTransaction {
for (Model m in batch) {
m.save()
}
}
}
さらに、を防ぐために、メソッドにオブジェクトOutOfMemoryExceptions
を含め、SessionFactory
現在のセッション オブジェクトを取得しsession.clear()
、定期的に でクリアすることができます。
この更新の前は、 で行を更新するのに 53 秒かかっていましたがsave()
、現在は 800 行を更新するのに 794 ミリ秒かかっています。
これは役立つかもしれません: http://geekcredential.wordpress.com/2012/05/25/bulk-insert-with-grails/
grails GORM をバイパスし、HQL レベルに下がってオブジェクトを挿入または更新できます。これにより、メモリを消費する検証オブジェクト、エラー、その他がないため、メモリ不足の例外が発生する可能性が低くなります。もう 1 つの方法は、挿入または更新のたびにセッションをフラッシュし、検証エラーとオブジェクトをクリアすることです。