laravel游标和laravel块方法有什么区别?

新手上路,请多包涵

我想知道 laravel 块和 laravel 游标方法有什么区别。哪种方法更适合使用?它们的用例是什么?我知道你应该使用游标来节省内存,但它在后端是如何工作的呢?

带有示例的详细解释会很有用,因为我在 stackoverflow 和其他网站上进行了搜索,但没有找到太多信息。

这是 laravel 文档中的代码片段。

分块结果

Flight::chunk(200, function ($flights) {
    foreach ($flights as $flight) {
        //
    }
});

使用游标

foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
    //
}

原文由 Suraj 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 507
2 个回答

事实上,这个问题可能会吸引一些固执己见的答案,但是 Laravel Docs 中提供了简单的答案

仅供参考:

这是块:

如果您需要处理数千条 Eloquent 记录,请使用 chunk 命令。 chunk 方法将检索 Eloquent 模型的“块”,将它们提供给给定的 Closure 进行处理。使用 chunk 方法将在处理大型结果集时节省内存:

这是游标:

cursor 方法允许您使用游标遍历数据库记录,这只会执行一个查询。在处理大量数据时,可以使用 cursor 方法来大大减少你的内存占用:

Chunk 从数据库中检索记录,并将其加载到内存中,同时将游标设置在检索到的最后一条记录上,这样就不会发生冲突。

所以这里的好处是,如果你想在 记录发出前重新格式化,或者你想每次对第n条记录进行操作,那么这很有用。一个例子是,如果您正在构建一个视图输出/excel 表,那么您可以记录计数直到它们完成,这样它们就不会立即加载到内存中,从而达到内存限制。

Cursor 使用 PHP 生成器,您可以查看 php 生成器 页面,但这里有一个有趣的标题:

生成器允许您编写使用 foreach 迭代一组数据的代码,而无需在内存中构建数组,这可能会导致您超出内存限制,或者需要大量处理时间才能生成。相反,您可以编写一个生成器函数,它与普通 函数 相同,除了不是 返回 一次,生成器可以根据需要多次 yield 以提供要迭代的值。

虽然我不能保证我完全理解 Cursor 的概念,但是对于 Chunk,chunk 在每个记录大小上运行查询,检索它,并将它传递到闭包中以进一步处理记录。

希望这是有用的。

原文由 Oluwatobi Samuel Omisakin 发布,翻译遵循 CC BY-SA 4.0 许可协议

我们有一个比较: chunk() vs cursor()

  • 光标():高速
  • chunk():常量内存使用

10,000 条记录

 +-------------+-----------+------------+
|             | Time(sec) | Memory(MB) |
+-------------+-----------+------------+
| get()       |      0.17 |         22 |
| chunk(100)  |      0.38 |         10 |
| chunk(1000) |      0.17 |         12 |
| cursor()    |      0.16 |         14 |
+-------------+-----------+------------+

100,000 条记录

 +--------------+------------+------------+
|              | Time(sec)  | Memory(MB) |
+--------------+------------+------------+
| get()        |        0.8 |     132    |
| chunk(100)   |       19.9 |      10    |
| chunk(1000)  |        2.3 |      12    |
| chunk(10000) |        1.1 |      34    |
| cursor()     |        0.5 |      45    |
+--------------+------------+------------+
  • TestData:Laravel默认迁移的users表
  • 家园 0.5.0
  • PHP 7.0.12
  • MySQL 5.7.16
  • 拉维尔 5.3.22

原文由 mohammad asghari 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏