PHP脚本超出数据库选择的内存限制
我指的是我一直在写的代码: 当我打开网站时,这一行正在登录到error.log。它加载了大量数据(超过120k个)条目 所以mysqli_stmt_fetch经常被调用。对于每个条目,将创建一个对象并将其推送到数组上 我能做些什么来优化这段代码吗?让它使用更少的内存。我知道有增加内存的方法,也有克隆,但是我不能使用它,因为每次调用mysqli_stmt_fetch都会设置$row属性,这些属性通过引用传递 或者,对于这个调用,我可以使用COUNT语句而不是SELECT语句,但是我正在尝试修复一个可能的内存泄漏 即使是该代码也存在同样的问题:PHP脚本超出数据库选择的内存限制,php,mysql,Php,Mysql,我指的是我一直在写的代码: 当我打开网站时,这一行正在登录到error.log。它加载了大量数据(超过120k个)条目 所以mysqli_stmt_fetch经常被调用。对于每个条目,将创建一个对象并将其推送到数组上 我能做些什么来优化这段代码吗?让它使用更少的内存。我知道有增加内存的方法,也有克隆,但是我不能使用它,因为每次调用mysqli_stmt_fetch都会设置$row属性,这些属性通过引用传递 或者,对于这个调用,我可以使用COUNT语句而不是SELECT语句,但是我正在尝试修复一
while (mysqli_stmt_fetch($prep)) {
$obj = new stdClass();
foreach ($info as $key => $value) {
$obj->$value = $row->$value;
}
array_push($resultArray,$obj);
unset($obj); //unset the object
}
欢迎提出任何意见
- xCoder(共享数据)
我不主张将此作为推荐的方法,因为它会引入复杂性并使用额外的CPU来压缩/解压缩,但如果您没有其他选择并且必须将它们保留在内存中,则这是一种可能的解决方案。使用PDO而不是mysqli,并执行以下操作:
$result = $query->fetchAll(PDO::FETCH_OBJ);
为您提供一个以列名为键(以db值为值)的对象数组。
相当整洁。。不需要while循环您可以使用。优点是它们产生每个元素,而不是将它们全部写入系统内存
function my_object_generator($prep) {
while ($info=mysqli_stmt_fetch($prep)) {
$obj = new stdClass();
foreach ($info as $key => $value) {
$obj->$value = $row->$value;
}
yield $obj;
}
}
$read_transformed_data = my_object_generator($prep);
foreach ($foo in $read_transformed_data) {
print($foo);
}
一个优点是,您不需要成批处理数据。
一个缺点是无法计算数据的长度。但是在重数据集上,应该使用mysql计数函数来实现这一目的。还要注意,不要再次将生成器输出收集到另一个阵列中。这将导致与以前相同的问题 实现分页。很有可能你正在试图一次水合数千个对象。它怎么能使用更少的内存呢?您正在将整个结果集提取到内存中。要么检索更少的数据,要么不要一次就把所有数据都吸进去。这可能会增加php的内存限制,这只会在数据集增长时推迟问题的发生。请注意,您的foreach循环是无点的。mysqli可以直接获取一个对象,不需要自己从结果数组复制到一个对象中。没有内存泄漏。内存不足。这是一个巨大的差异,短缺来自于你试图添加超过杯子容量的水。唯一可能的解决办法是你不加那么多的水。很简单,对吗?我的回答解决了你的问题吗?那是如何停止内存消耗的?我只是希望尝试一下,php的内部内存使用魔法比我自己的更好。从我的快速浏览中可以看出,DbManager的其余部分应该使用它。但也许我两句话都太乐观了。可悲的是,这是一回事。有两种选择-
SplFixedArray
或Judy
阵列,这可能会降低消耗。然而,唯一明智的做法是不要将整个数据库提取到具有内存限制的php中:)遗憾的是,这是错误的。压缩所有您喜欢的内容,将整个数据集粘贴到任何愚蠢的想法中。您仍然可以耗尽内存来保存数据。唯一的解决办法不是什么都取。