Larvel毫无疑问的Fasad内存使用

问题描述 投票:2回答:2

我找到了用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

使用laravel的illuminate/database组件和非常相似的方法DB::table('playlists')->limit(50000)->get();也使用35mb的内存。

  • 如何使用Laravel的eloquent或DB facade实现第一种方法?
  • 你能否建议一些文章如何发展内存使用的差异?

谢谢

php laravel memory pdo
2个回答
4
投票

当您使用php(mysql函数或PDO)执行SQL查询时,从查询返回的所有数据都作为“结果集”加载到内存中。

为了在“结果集”中使用数据,你必须在常规的php数组/对象中获取它们。

PDOStatement :: fetch - 从结果集中取出一行到内存中。

PDOStatement :: fetchAll - 将结果集中的所有行提取到内存,从而使内存使用量翻倍。

Eloquent具有chunk结果集的能力。这相当于在PDO中执行“X次提取”。

但是,如果您正在使用非常大的结果集,请考虑使用SQL限制。


2
投票

像这样处理大型数据集的Laravel方法是使用chunking

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

这确保了不超过块大小(在我的示例中,1000行)一次加载到RAM中。 1k是任意的;你可以分块1,100,253等

© www.soinside.com 2019 - 2024. All rights reserved.