正規化されていない同じタイプのデータを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');