Quantcast
Channel: polidog lab++
Viewing all articles
Browse latest Browse all 48

Doctrine2でバルクインサートする場合の注意点

$
0
0

元部下で変態なFさんがFacebookで書いてたのと、自分なりのまとめということで、簡単にDoctrine2のバルクインサートについて書いておこうと思います。

使用しているDBはMySQL想定です。
Doctrine2を使ってバルクインサートする場合は以下のようなコードになるかと思います。

<?php
    $batch = 1000;
    foreach ($entities as $key => $entity) {
      $em->persist($entity);
      if ($key % $batch == 0) {
        $em->flush();
      }
    }

で、まあこれはこれでいいんですが、いくつかトラップがあると思います。
まあどれもメモリが足りなくなる問題だと思いますが・・・

1. clearをしていない
まあO/Rマッパーなんで、いろいろとメモリを食うわけです。
んで、解放しないままにしておくと、メモリが足りなくなるわけです。
これはentityManagerのclearメソッドを実行すればいいのです。
<?php
    $batch = 1000;
    foreach ($entities as $key => $entity) {
      $em->persist($entity);
      if ($key % $batch == 0) {
        $em->flush();
        $em->clear();
      }
    }
2. clearしたらなんか他のエンティティを保存しようとしたらExceptionを吐く
どういう状況だったか忘れてしまいましたが、複数のエンティティが絡むバッチ処理を実行している際にclear()をしてしまうとエラーになるという現象が発生したことがありました。
これは多分なんですが、clear時にエンティティ名を指定しないとダメなんだと。
<?php
    $batch = 1000;
    foreach ($entities as $key => $entity) {
      $em->persist($entity);
      if ($key % $batch == 0) {
        // Pdw\TestBundle\Entity\Hogeエンティティを扱っている事を想定
        $em->flush();
        $em->clear('Pdw\TestBundle\Entity\Hoge');
      }
    }
3. Commandとして実行した場合にメモリが足りなくなる問題
ContainerAwareCommandクラスを継承した、コマンド系の処理を実行している際にメモリが足りなくなる事があります。
これは開発環境でよく起きる現象かと思っています。
実行するときに「–no-debug 」オプションをちゃんと指定すれば大丈夫です。
app/console hoge:fuag --no-debug 

と以上が、大まかな注意点だと使っていて感じました。
まあ僕がDcotrine2を全然使いこなせていないので、、、もっといろいろノウハウを持っている方は僕に共有してください。
有益な情報であれば鰻ぐらいはおごりますよ。

それから、DQLのパース処理が遅いのか、バルクインサートしてもなんか遅い感じがします。
1秒近く待たされてからInsert処理が実行されるぽい感じです。。
まあPDOが遅い上にDQLとか遅いのは仕方ないよねって感じですね。

あまりにも大きすぎる処理をのぞいてある程度はバッチ処理であれば、phpのメモリを512MBぐらいすれば大体たりるかなぁーというイメージです。
てか大体メモリー食う時って自分の実装が悪いってのが90%ぐらいなんで常に自分の実装を見直す癖はつけた方が良いです。

てかそもそもバッチ処理にDcotrine2を使う必要ないのでは?って思ってしまう今日この頃です。


Viewing all articles
Browse latest Browse all 48

Trending Articles