LoginSignup
1
1

More than 5 years have passed since last update.

正規化されていないデータを集計する際にメモリ消費量を抑える方法

Last updated at Posted at 2018-05-07

正規化されていない同じタイプのデータをCONCAT_WSで結合して取ってくる。
こうするとメモリ使用量を抑えることができます。
たぶんNULLカラムの個数が多いほど効果あると思います。
逆にNULLカラムが存在しない場合はたぶん効果ないと思います…。
コレクションで何やかんやしたい場合は使えませんがデータ集計のバッチとかでは使えるかなと。
とある案件で数百万件のデータを集計する際に20GBほど消費していたのがこの方法で半分の10GBになりました。
(リセマラ…コロス)

$data = [];
ModelClass::selectRaw("
        id,
        user_id,
        CONCAT_WS(',', card_id01, card_id02, card_id03, card_id04) as card_ids,
        CONCAT_WS(',', sub_card_id01, sub_card_id02, sub_card_id03, sub_card_id04) as sub_card_ids,
        CONCAT_WS(',', weapon_id01, weapon_id02, weapon_id03, weapon_id04) as weapon_ids
    ")
    ->orderBy('id')
    ->chunk(10000, function ($chunk) use (&$data) {
        foreach ($chunk as $v) {
            $row = $v->toArray();
            unset($row['id']);
            $data[] = $row;
        }
    });

カラム名がidでない時はchunkByIdを使う。
chunkを使ってもエラーが出ないので注意。

$data = [];
ModelClass::selectRaw("
        primary_id,
        user_id,
        CONCAT_WS(',', card_id01, card_id02, card_id03, card_id04) as card_ids,
        CONCAT_WS(',', sub_card_id01, sub_card_id02, sub_card_id03, sub_card_id04) as sub_card_ids,
        CONCAT_WS(',', weapon_id01, weapon_id02, weapon_id03, weapon_id04) as weapon_ids
    ")
    ->orderBy('primary_id')
    ->chunkById(10000, function ($chunk) use (&$data) {
        foreach ($chunk as $v) {
            $row = $v->toArray();
            unset($row['primary_id']);
            $data[] = $row;
        }
    }, 'primary_id');
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1