PHP脚本超出数据库选择的内存限制

PHP脚本超出数据库选择的内存限制,php,mysql,Php,Mysql,我指的是我一直在写的代码: 当我打开网站时,这一行正在登录到error.log。它加载了大量数据(超过120k个)条目 所以mysqli_stmt_fetch经常被调用。对于每个条目,将创建一个对象并将其推送到数组上 我能做些什么来优化这段代码吗?让它使用更少的内存。我知道有增加内存的方法,也有克隆,但是我不能使用它,因为每次调用mysqli_stmt_fetch都会设置$row属性,这些属性通过引用传递 或者,对于这个调用,我可以使用COUNT语句而不是SELECT语句,但是我正在尝试修复一

我指的是我一直在写的代码:

当我打开网站时,这一行正在登录到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(共享数据)

如果您确实需要将它们全部存储在内存中,并且不能一次只获取较少的条目,那么作为最后手段,您可以在数组中存储每个对象的序列化+压缩字符串,然后根据需要取消序列化+解压缩

看到和

作为提示,如果压缩一组序列化对象(比如每个子数组有100个对象,并且序列化+压缩每个子数组),则可能会节省更多内存


我不主张将此作为推荐的方法,因为它会引入复杂性并使用额外的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中:)遗憾的是,这是错误的。压缩所有您喜欢的内容,将整个数据集粘贴到任何愚蠢的想法中。您仍然可以耗尽内存来保存数据。唯一的解决办法不是什么都取。