[英]PHP PDO fetch() loop dies after processing part of large dataset
我有一个 PHP 脚本,它在一个典型的循环中将来自 PDO 查询的“大”数据集(大约 10 万条记录)处理为单个对象集合:
while ($record = $query->fetch()) {
$obj = new Thing($record);
/* do some processing */
$list[] = $obj;
$count++;
}
error_log('Processed '.$count.' records');
这个循环处理了大约 50% 的数据集,然后莫名其妙地中断了。
我尝试过的事情:
memory_get_peak_usage()
在循环终止之前始终输出大约 63MB。 内存限制为 512MB,通过 php.ini 设置。set_time_limit()
将脚本执行时间增加到 1 小时(3600 秒)。 循环在那之前很久就中断了,我在日志中没有看到这个错误的常见错误。PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
设置为false
以避免缓冲整个数据集$query->errorInfo()
。 这没有帮助,因为错误代码是“00000”。其他奇怪的行为:
ini_set('memory_limit', '1024MB')
设置内存限制时,循环实际上比使用较小的内存限制更早结束,进度约为 20%。如果这有什么不同,我将使用 MAMP PRO 在本地完成所有这些操作。
有没有其他东西可以持续打破我没有检查过的这个循环? 这难道不是处理这么多记录的可行策略吗?
使用批处理策略(以 20K 为增量)后,我开始在第三批MySQL server has gone away
始终看到 MySQL 错误: MySQL server has gone away
; 可能是长时间运行的无缓冲查询的症状。
如果您真的需要动态处理 100K 条记录,您应该在 SQL 中进行处理,并根据需要获取结果 - 这应该可以节省大量时间。
但是由于某种原因,您可能无法这样做。 你总是处理语句中的所有行,所以使用 fetchAll 一次 - 然后让 MySQL 单独使用,就像这样:
$records = $query->fetchAll()
foreach ($records as record)
{
$obj = new Thing($record);
/* do some processing */
$list[] = $obj;
$count++;
}
error_log('Processed '.$count.' records');
此外,仅选择您将使用的行。 如果这没有帮助,您可以尝试这样做: 使用 PDO 设置连接超时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.