使用 CakePHP 的 saveMany() 保存 >10000 条记录
Posted
技术标签:
【中文标题】使用 CakePHP 的 saveMany() 保存 >10000 条记录【英文标题】:Save >10000 records with CakePHP's saveMany() 【发布时间】:2012-03-04 12:05:33 【问题描述】:我正在尝试使用 Cakephp 2.1 的方法 saveMany()
保存超过 10000 条记录的列表。但它给了我一个 500 错误,或者一个“内存耗尽”的致命错误。
如果我在处理完整个数组后对其进行调试(因此,不调用 save 方法),时间在 0.05 秒以下。但是当我添加保存方法($this->saveMany($save, array('validate' => false));
)时,它向我显示了上述错误之一。
我提到我在 mysql 中使用 InnoDB 作为存储引擎,使用 PHP 作为脚本语言。
我做错了什么,我该如何解决?
编辑
我回到这个问题,因为我“解决了”为什么大量记录无法保存。原因是……好吧,甚至一条记录都没有保存。我测试了只保存生成的数组中的第一个元素,这就是它发生的情况:它增加内存直到限制,然后它死了。我已经把它放在我的本地主机上,有 2GB 的内存,它仍然给我超出内存的错误。这很奇怪,我不明白为什么会这样。应用于另一个模型的相同代码按预期工作。我重新创建了模型及其表,但没有成功。我能想到的唯一原因是表名的长度,但这对我来说毫无意义。仅仅为了保存一条记录,什么会导致内存增加?
【问题讨论】:
您需要多久执行一次此操作? 10000 条记录从何而来?您需要提供更多信息,以便人们提出替代方法。 我正在为我的应用程序构建一个缓存,这样每当我需要检索和计算一些数据时,我只需要从这 10000 条记录中获取几条记录。我只会这样做几个次,手动。所以脚本的唯一要求是实际工作。 更新了我的答案。您可以访问 MySQL 控制台吗? 这很奇怪。您应该注释掉模型中的所有验证规则,以确保它们不会以任何方式影响。也尝试使用较小的结果集,如 10 行。将 debug 设置为 2 看看 sql dump 是否有什么奇怪的地方。 我解决了这个问题。我正在覆盖 Cake 方法并导致无限循环。很傻。感谢您的所有帮助,将您的答案标记为已接受:) 【参考方案1】:保存 10000 行可能需要一段时间。确保你已经将php的时间限制set_time_limit(120);
设置得足够大。
您也可以尝试像这样一一保存记录:
foreach($save as $s)
$this->create();
$this->save($s, array('validate' => false));
编辑 1:
但如果原始数据来自数据库,您可以使用 MySQL 控制台或使用 $this->query();
将其直接复制到缓存表中
或者你可以SELECT
它INTO OUTFILE
和LOAD DATA INFILE
它到缓存表。
编辑 2:
然后我想到的唯一一件事就是将数据保存到磁盘上的文本文件中,然后在另一个函数中读取它,然后在时间/内存限制允许的时间保存尽可能多的行。您也可以尝试将其保存在 csv 文件中并使用 $this->query('LOAD DATA LOCAL INFILE xxx ...');
我想到你应该在保存之前禁用索引以使它们更快。你可以使用$this->query('ALTER TABLE table DISABLE KEYS;');
来做到这一点
【讨论】:
它仍然没有走到最后。它再次发出内存超出错误。我无法更改内存/时间限制,因为我在付费主机上。 我无权访问控制台,也无法完全复制它,因为我需要对表中的数据执行一些操作。只有在修改数据以进行缓存后,才应保存它。以上是关于使用 CakePHP 的 saveMany() 保存 >10000 条记录的主要内容,如果未能解决你的问题,请参考以下文章
cakephp saveMany 使用 $fieldList (无表单)