ジェネレータとSQL
SQL の結果をなめたいがメモリにぜんぶ展開すると out of memory になりがちなところ、 チャンクを次々とジェネレータで供給するというパターンを思いついた。これならほぼ定数メモリで大量のデータを処理できる。
ジェネレータは Iterator を実装しているので、SPL のイテレータにわたすこともできる。
function chunk(SQL $query, int $size) : Iterator { $offset = 0; $query->limit($size); while ($result = fetch_all($query)) { yield from $result; $query->offset($offset += $size); } } $query = sql("SELECT * FROM sakila.film"); // SQL を表すナニカ foreach (chunk($query, $size = 1000) as $film) { # do useful stuff }
実際は offset ではなく、id ベースでたどるのがよさそうではある。