Laravel dabatabse 门面内存使用情况

Eva*_*kus 3 php memory pdo laravel

我发现了用 php pdo 编写的很棒的示例,它有助于迭代大量数据,而无需为整个结果集实际分配内存:

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

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

我做了一个调查,这种方法使用18mb了内存。

如果我获取所有这样的结果,$results = $statement->fetchAll(PDO::FETCH_ASSOC);内存使用量会上升到35mb.

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

  • 如何使用 Laravel 的 eloquent 或 DB 外观实现第一种方法?
  • 您能否推荐一些文章,这种内存使用差异是如何发展的?

谢谢

Yar*_*dam 5

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

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

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

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

Eloquent 能够对结果集进行分。这相当于在 PDO 中执行“X 次提取”。

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

  • @EvaldasButkus 每个块执行一次将 100 行加载到内存中。在第二个块中,第一个块被第二个块覆盖。所以峰值内存使用理论上应该是结果集+块大小。 (2认同)