【问题标题】:Yii findAll() causes memory issueYii findAll() 导致内存问题
【发布时间】:2023-04-10 12:11:02
【问题描述】:

我的记录只有 15000 条。php 配置使用的内存是 128 mb。所以我得到了这个错误。

允许的内存大小为 134217728 字节已用尽

有两种方法可以解决这个问题。

  1. http://www.yiiframework.com/doc/guide/1.1/en/database.dao
  2. 增加 PHP 中允许的内存

我很困惑的是,如果我将允许的内存增加到 256,有一天当数据数变为 30 000 时,这个错误会再次出现。

所以我在开发大型应用程序时不应该使用 Yii cactiverecord findAll() 吗?或者我应该随着更多数据的进入而不断增加内存大小。

最好的方法是什么?

【问题讨论】:

  • createCommand 用于自定义查询,即;仅获取您需要的内容并使用索引。
  • 这不是一个非常大的模型数组的真正解决方案,但你可以做的是 user ->select() 只选择你需要的数据,所以如果你想显示一个不需要 id 的名称,电子邮件摘录。比你能做的是 Customer::find()->select('name')->all()

标签: php memory mysqli yii yii2


【解决方案1】:

我有同样的问题,经过几天的研究,问题是 activeRecord 的对象与其关系的所有对象都进入内存,这使得增加占用内存,所以我的解决方案是制作取消该关系对象和该对象本身的函数每次循环时,在该对象类模型中添加以下代码,如下所示:

class ModelObject{
   ....

   public function unsetModel()
   {
       foreach($this->getRelatedRecords() as $name => $record)
       {
           unset($this->{$name});
       }
       unset($this);
   }

   ....
}

并像这样在 foreach 中调用该函数:

foreach($modelObjects as $model)
{
     ....

     $model->unsetModel();
}

【讨论】:

    【解决方案2】:

    尝试批量检索数据:

    http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#data-in-batches

    // fetch 10 customers at a time
    foreach (Customer::find()->batch(10) as $customers) {
        // $customers is an array of 10 or fewer Customer objects
    }
    
    // fetch 10 customers at a time and iterate them one by one
    foreach (Customer::find()->each(10) as $customer) {
        // $customer is a Customer object
    }
    
    // batch query with eager loading
    foreach (Customer::find()->with('orders')->each() as $customer) {
        // $customer is a Customer object with the 'orders' relation populated
    }
    

    【讨论】:

    • 哈。我使用了 CDataProviderIterator 的移植版本来执行此操作。傻我。
    • @dev1234 这取决于。每个批次都是一个新的 sql 查询,因此需要更长的时间。您可以调整批处理大小以获得最佳速度和内存使用率。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多