Laravel Dabatabse门面内存使用情况

时间:2019-03-06 18:41:08

标签: php laravel memory pdo

我发现了一个用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的雄辩或DB Facade实现第一种方法?
  • 您能否建议一些文章,介绍这种内存使用差异如何发展?

谢谢

2 个答案:

答案 0 :(得分:4)

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

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

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

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

雄辩的人有能力chunk个结果集。这等效于在PDO中执行“ X次提取”。

但是,如果要处理非常大的结果集,请考虑使用SQL限制。

答案 1 :(得分: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等块化。