Использование памяти фасада Laravel dabatabse - PullRequest
2 голосов
/ 06 марта 2019

Я нашел отличный пример, написанный на php pdo, который помогает перебирать огромный объем данных без фактического выделения памяти для всего набора результатов:

    $sql = 'SELECT * from playlists limit 50000';
    $statement = $pdo->prepare($sql);
    $statement->execute();

    while (($result = $statement->fetch(PDO::FETCH_ASSOC)) !== false) {
        //do something
    }

Я провел расследование, и этот подход использует 18mb памяти.

Если я получу все результаты, подобные этому, $results = $statement->fetchAll(PDO::FETCH_ASSOC); использование памяти увеличится до 35mb.

Использование компонента illuminate/database laravel и очень похожий подход DB::table('playlists')->limit(50000)->get(); также использует 35mb памяти.

  • Как я могу достичь первого подхода, используя красноречивый Laravel или фасад DB?
  • Не могли бы вы предложить несколько статей, как развивается эта разница в использовании памяти?

Спасибо

Ответы [ 2 ]

4 голосов
/ 06 марта 2019

Когда вы выполняете SQL-запрос с php (либо функции mysql, либо PDO), все данные, возвращаемые из запроса, загружаются в память как «набор результатов».

Для использования данных в «наборе результатов»Вы должны извлекать их в обычных массивах / объектах php.

PDOStatement :: fetch - извлекает одну строку из набора результатов в память.

PDOStatement:: fetchAll - извлекает все строки из набора результатов в память, удваивая использование памяти.

Eloquent имеет возможность chunk наборов результатов.Это эквивалентно выполнению «выборки X раз» в PDO.

Однако, если вы работаете с очень большими наборами результатов, подумайте об использовании ограничений SQL.

2 голосов
/ 06 марта 2019

Подход Laravel к обработке больших наборов данных, подобный этому, заключается в использовании chunking .

DB::table('playlists')->chunk(1000, function($playlists) use($count) {
    foreach($playlists as $playlist) {
        // do something with this playlist
    }
});

Это гарантирует, что в ОЗУ одновременно загружается не более, чем размер чанка (в моем примере это 1000 строк). 1k произвольно; Вы могли бы кусок 1, 100, 253 и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...