在 CakePHP 中使用 find('all') 处理大量数据时,我遇到了内存不足的问题。[我尝试过了,但是……]

这是开发团队的 Hase。

前几天,我尝试
在 CakePHP 中使用 `find('all')` 检索近 100,000 个数据项,但内存不足,
出现了以下错误。

已用完允许的内存大小 134217728 字节

所以我研究了各种方法来减少内存使用量并检索近 10 万行数据。

当前代码

$data = $this->Model->find('all'); // 执行某些操作 .........

使用 query()

看来使用 query() 函数检索数据比使用 find('all') 函数检索数据更轻量级。
因此,我修改了代码,用 query() 函数代替 find 函数来检索数据。

$data = $this->Model->query("SELECT * FROM hogehoge;"); // 进行一些处理.........

结果

情绪处理变得更加容易我感觉但,
就像我使用 find('all') 检索时一样,由于内存不足而发生错误。

禁用 query() 缓存

查看官方文档,似乎 `query()` 默认会缓存查询结果。
要禁用此查询缓存,
可以将第二个参数指定为 `false`,例如:`query($query, $cachequeries = false)`。
因此,我尝试将 `query()` 的第二个参数指定为 `false`。

$data = $this->Model->query("SELECT * FROM hogehoge;", $cachequeries = false); // 进行一些处理 .........

结果

总之,没有发生任何特别的变化。

使用循环分批检索数据

上述方法仍然一次性检索 10 万个数据点,因此
不可避免地会耗尽内存。
所以,我尝试使用 limit 和 offset,通过循环将数据分割成更小的块。

// 获取数据项的数量 $count = $this->Model->find('count'); // 一次检索 5000 条数据 $limit = 5000; // 循环次数({数据项总数 ÷ 一次检索的数据项总数} 向上取整) $loop = ceil($count / $limit); for ($i = 0; $i < $loop; $i++){ // 偏移量 $offset = $limit * $i; $data = $this->Model->query("select * from hogehoge as limit {$limit} offset {$offset};", $cachequeries = false); // 进行一些处理 ......... }

结果

结果太棒了!
没有出现内存错误,数据也正确检索到了,一切正常!

所以,如果有人遇到同样的问题,希望这能有所帮助。

就这样。

然而,使用这种方法……
详情请参见此处。
在 CakePHP 中使用 find('all') 处理大量数据时,我遇到了内存不足的问题 [解决方案] | Beyond Co., Ltd.

如果您觉得这篇文章对您有帮助,请点个“赞”!
1
加载中...
1票,平均分:1.00/11
8,254
X Facebook Hatena书签 口袋

这篇文章的作者

关于作者

长谷达也

应届毕业生加入 Beyond Co., Ltd.。

我们开发网络系统(开发基于浏览器的服务和系统,例如网络服务、数字内容和业务管理系统)和游戏 API(开发用于与应用程序游戏通信的程序)。

我们也为 Shopify 开发私有/定制应用程序。

最初在大阪办公室工作,2019 年调到横滨办公室。
爱好:棒球、卡拉OK、动漫。