2012-05-11 19 views
1

大きなcsvファイルの処理に取り掛かっていて、バッチインポートに関するこの記事が見つかりました:http://naleid.com/blog/2009/10/01/batch-import-performance-with-grails-and-mysql/私も同じことをやろうとしましたが、効果がないようです。Grailsのフラッシングが有効でない

各フラッシング後にインスタンスをデータベースで表示できますか? 'SELECT COUNT(*)FROM TABLE1'をクエリしようとすると、今や0またはすべてのエンティティが存在するので、インスタンスが一度にコミットされるように見えます。

次に、空のテーブルに初めてインポートするときにインポートがすばやく機能することに気づきましたが、テーブルがいっぱいで、エンティティを更新するか、新しいものとして保存する必要がある場合、プロセス全体が非常に遅くなります。これは、主にメモリがクリーニングされていないために発生し、1MB以下に減少し、アプリケーションが停止します。それで、セッションをフラッシュしないのでですか?

インポートするための私のコードはここにある:

public void saveAll(List<MedicalInstrument> listMedicalInstruments) { 
    log.info("start saving") 
    for (int i = 0; i < listMedicalInstruments.size() - 1; i++) { 
     def medicalInstrument = listMedicalInstruments.get(i) 
     def persistedMedicalInstrument = MedicalInstrument.findByCode(medicalInstrument.code) 
     if (persistedMedicalInstrument) { 
      persistedMedicalInstrument.properties = medicalInstrument.properties 
      persistedMedicalInstrument.save() 
     } else { 
      medicalInstrument.save() 
     } 
     if ((i + 1) % 100 == 0) { 
      cleanUpGorm() 
      if ((i + 1) % 1000 == 0) { 
       log.info("saved ${i} entities") 
      } 
     } 
    } 
    cleanUpGorm() 
} 

protected void cleanUpGorm() { 
    log.info("cleanin GORM") 
    def session = sessionFactory.currentSession 
    session.flush() 
    session.clear() 
    propertyInstanceMap.get().clear() 
} 

は、任意の助けをありがとうございました!

よろしく、

Lojza

P.S:私のJVMのメモリは合計で252.81メガバイトを持っているが、それは私だけのために環境をテストし、他の3人です。

答えて

0

私の経験から、それらはすべて最後にコミットされるまでデータベースに必ず表示されるとは限りません。私はOracleを使用しています。バッチごとに個別のトランザクションを作成し、フラッシュ後にクローズするだけで、バッチでコミットできるようにしています。しかし、最終的なフラッシュ時にプロセスの最後にエラーが発生しました。私はそれを把握する時間がありませんでした。上記のプロセスを使用すると、データロードの大きさにかかわらず問題はありませんでした。

この方法を使用すると、大いに役立ちます。セッションをフラッシュしてクリアします。あなたはそれを見るためにあなたのメモリ使用率を見ることができます。

レコードを持つテーブルを更新する限り、テーブルにインデックスがありますか?場合によっては、データベースがインデックスを最新の状態に保つためにインデックスがこのような一括挿入/更新を遅らせることがあります。インポート/アップデート前にインデックスを無効にしてから、有効にした場合

+0

ありがとうございました。私は合計で25の列のうちの2つだけにインデックスを持っているので、データベースにとってそれほどの仕事ではないと思います。私は主なエラーは不十分なメモリだと思う。私はJVMのために252.81 MBを持っています。私がインポートしているときに空きメモリが1 MBに減少していることに気付きました。その後、プロセス全体が大幅に遅くなります。今では、インポートプロセスを途中で1秒間スリープ状態にして、GCがその作業を行い、メモリを解放できるようにするアイディアを得ました。どう思いますか? –

+0

Grailsは実際に何もしなくてもメモリ豚のようなものです。 250Mはそれほどではありません - あなたは100レコードごとに少し頻繁に整理したいかもしれません。また、JVMがGCを支援するためのメモリパラメータをチューニングする際に白紙がたくさんあります。私は間違いなくそれらを見ています。 – Kelly

+0

私は100回ごとの記録をフラッシュします。また、あなたのクレアアップは最終的にブロックされなければなりません。セッションできれいにしてください。 – allthenutsandbolts

6

私は一度同様の問題を抱えていました。それから、私はgrailsサービスでそれをやっていたのですが、その理由はデフォルトでトランザクションであったからです。そのため、サービス内のメソッドへの呼び出しはすべて、そのデータベースに変更を加えたトランザクションでラップされ、メソッドが完了するまで結果がフラッシュされませんでした。

関連する問題