【问题标题】:Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 20480 bytes) in Codeigniter致命错误:Codeigniter 中允许的内存大小为 268435456 字节已用尽(尝试分配 20480 字节)
【发布时间】:2020-09-06 16:47:50
【问题描述】:

在 mysql 中获取超过 30 万条记录时,我遇到了这样的错误

致命错误:允许的内存大小为 268435456 字节已用尽(尝试分配 20480 字节)

Project\system\database\drivers\mysqli\mysqli_result.php 在第 229 行。

我已将 memory_limit 增加到 1024M 并更改为 -1。

我找不到解决办法,直到

【问题讨论】:

  • 我认为花时间研究如何更有效地处理数据会更有用。您真的需要同时加载所有记录吗?
  • 是的,我想快速加载所有数据
  • 有什么用?了解您为什么需要这些数据以及如何使用它可能有助于解决您的问题,目前没有任何人可以做。
  • 为什么你不能限制获取的项目数量并将其分成更小的块?但是你必须对数据做一些事情并从内存中销毁它。否则你会遇到同样的错误。
  • 欢迎,为了提高您在 SO 上的体验,请阅读how to askOn Topic question,然后查看Question Check listthe perfect question,如何创建Minimal, Complete and Verifiable Exampletake the tour

标签: php codeigniter cpanel memory-limit


【解决方案1】:

改用PHP Generators

function getData()
{
    $sql = 'SELECT * FROM table';
    $q= $this->conn->prepare($sql);
    $q->execute();
    while ($row = $q->fetch(PDO::FETCH_ASSOC)) {
        yield $row;
    }
}

foreach ($this->getData() as $record) {
    //
}

【讨论】:

  • 与将所有代码放在yield $row; 所在的位置相比,这样做有什么优势?
  • 生成器允许您编写使用 foreach 迭代一组数据的代码,而无需在内存中构建数组,这可能会导致您超出内存限制,或者需要大量生成的处理时间。相反,您可以编写一个与普通函数相同的生成器函数,不同之处在于生成器不是返回一次,而是生成器可以根据需要多次生成以提供要迭代的值。
  • 做一些关于 PHP 生成器的研究 (php.net/manual/en/language.generators.overview.php)
  • 我的意思是,您可以在while ($row = $q->fetch(PDO::FETCH_ASSOC)) { 循环中包含相同的代码,而不是处理foreach() 中的数据。因此,与其缩短此时间,不如在流程中添加一个额外的循环。
  • 恐怕,我对 Codeigniter 了解不多。我确定 codeigniter 也提供原始查询执行?
猜你喜欢
  • 2021-08-13
  • 2020-04-10
  • 2014-03-07
  • 2014-02-07
  • 2014-09-27
  • 2020-07-13
  • 2019-06-30
  • 1970-01-01
相关资源
最近更新 更多