1

Play フレームワーク 2.0 で単純な scala コードを試してデータベースを埋めようとしています (SQL ファイルをデータベース内に直接インポートするなど、他のオプションも存在しますが、それは重要ではありません)。

def filldb = Action {
  import play.api.db.DB
  import anorm._

  var result: Boolean = false

  val tuples: List[(Long, String)] = DB
    .withConnection("playground") { implicit c =>

      for (i <- 1 until 1000000) {
        SQL("""
            INSERT INTO article (
                id,
                title
            ) VALUES (
                """ + i + """,
                'Article no """ + i + """');"""
        ).executeUpdate()

        if (i % 1000 == 0) println("i:" + i)
      }

      val sqlQuery = SQL("select id, title from article order by id;")

      sqlQuery().map(row =>
        row[Long]("id") -> row[String]("title")).toList
    }
  Ok("done")
}

これはしばらくの間 (200K の繰り返し) うまく動作しますが、速度が低下し、徐々に (最大 1.8GB) メモリを消費し、最後にメモリ不足でクラッシュします。

誰かがこの動作の原因を説明できますか? さまざまな方法でコーディングできることは明らかですが、ポイントは、エラーが別のコンテキストで行われないように、何が間違っているかを理解することです...

詳細は次のとおりです。

  • OS:マック10.6.8
  • 再生: 2.0
  • データベース: mysql 5.5.12
  • テーブル :

    CREATE TABLE article (
    id bigint(20) NOT NULL UNIQUE,
    title varchar(255) NOT NULL,
    PRIMARY KEY (id)
    );
    

これを試してみましたが、これ以上成功しませんでした:

def filldb = Action {
  import play.api.db.DB
  import anorm._

  var result: Boolean = false
  val connection = DB.getConnection("playground")

  for (i <- 1 until 1000000) {
        SQL("""
            INSERT INTO article (
                id,
                title
            ) VALUES (
                """ + i + """,
                'Article no """ + i + """');"""
        ).executeUpdate()(connection)

        if (i % 1000 == 0) println("i:" + i)
      }

  val tuples: List[(Long, String)] = {

      val sqlQuery = SQL("select id, title from article order by id;")

      sqlQuery()(connection).map(row =>
        row[Long]("id") -> row[String]("title")).toList
    }

  connection.close()

  Ok("done")
}

良くない: 283k の繰り返しで立ち往生...

4

2 に答える 2

0

私の最初の推測では、メモリデータベースのデフォルトをまだ使用している可能性があります。conf / application.confがjdbc:h2:mem:playを使用していないことを確認できますか?もしそうなら、あなたのすべてのエントリはあなたの記憶をいっぱいにするでしょう。

また、作成する各ステートメントは、withConnectionブロックの終わりまで閉じられないステートメントオブジェクトを開きます。何百万ものそれらがメモリに座っているので、それは蓄積する可能性があります。http://www.playframework.org/documentation/2.0/ScalaDatabaseを参照してください

クエリ操作の外部でDBにデータを入力してみてください。私は1000のバッチを1000回実行して、それが問題を特定するかどうかを確認することを試みます。

于 2012-03-22T21:39:02.467 に答える