Przetwarzanie dużej ilości danych w mniejszych porcjach

0

W Laravelu mamy np. coś takiego

User::chunk(100, function ($users) {
  foreach ($users as $user) {
    $some_value = ($user->some_field > 0) ? 1 : 0;
    // might be more logic here
    $user->update(['some_other_field' => $some_value]);
  }
});

O ile wiem o co w tym chodzi, to nie rozumiem dlaczego jest to konieczne. To tak jakbyśmy zamiast jednego foreacha po 10 000 rekordach robili 100 foreachów po 100 rekordów, ale po co? Dlaczego przy przetwarzaniu 1 000 000 rekordów trzeba używać takich tricków?

0

Zacznijmy od tego, że wykorzystywanie foreacha do przetwarzania więcej niż kilku tysięcy rekordów samo w sobie stanowi patologię (choć może w PHP 7 to poprawili).

0

Bardziej mi chodziło o to dlaczego powstaje problem, do którego wymyślili rozwiązanie (właśnie w postaci chunkowania). Nie mam zbyt dużej wiedzy z zakresu działania komputerów, pamięci itp. dlatego byłbym wdzięczny gdybyście podpowiedzieli co można poczytać, bo trudno mi nawet znaleźć coś co pomoże mi w zrozumieniu tego.

0

Ach, tutaj rozchodzi się o co innego - nie podałeś całego przykładu :)
http://laraveldaily.com/process-big-db-table-with-chunk-method/

User::all() pobrałoby najpierw wszystkich użytkowników z bazy danych, a dopiero potem zaczęło ich przetwarzać (czyli np. przy milionie użytkowników w bazie, milion znalazłby się w pamięci).

User::chunk() pobiera dane seriami - np. po stu użytkowników. Czyli jeśli masz do przetworzenia milion użytkowników, najpierw do pamięci wczyta się i przetworzy pierwsza setka, potem ta setka jest usuwana z pamięci, wczytywana jest następna setka i tak do końca. Czyli maksymalnie jednocześnie w pamięci znajdzie się 100 użytkowników (a nie od razu milion).

0

Czyli rozumiem, że wszystko rozchodzi się o pamięć? Po prostu by zmienna tyle nie przetrzymała?

0

Nie "zmienna by tyle nie przetrzymała" (ponieważ to sformułowanie nie ma sensu), tylko niekoniecznie proces PHP/komputer miałby przydzielone tyle pamięci.

Wczytanie miliona użytkowników, gdzie każdy rekord składa się ze 128 bajtów, wymagałoby optymistycznie alokacji prawie 128 megabajtów pamięci, co dla aplikacji WWW stanowi... całkiem spory kawałek :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1