Yii渴望加载—致命错误:内存不足 [英] Yii eager loading — Fatal error: Out of memory

查看:104
本文介绍了Yii渴望加载—致命错误:内存不足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Yii的渴望加载有问题. 我打开用户个人资料页面并使用:

I have a problem with Yii eager loading. I open user profile page and use:

$model=User::model()->with('routes', 'likes', 'comments', 'questions', 'cityname')->findByPk($id);

关系是:

public function relations()
    {
        return array(
            'routes'=>array(self::HAS_MANY, 'Route', 'author_id', 'order'=>'routes.id DESC'),
            'questions'=>array(self::HAS_MANY, 'Question', 'author_id', 'order'=>'questions.id DESC'),
            'comments'=>array(self::HAS_MANY, 'Comment', 'author_id', 'order'=>'comments.id DESC',),
            'likes'=>array(self::HAS_MANY, 'Like', 'author_id', 'order'=>'likes.id DESC'),
            'cityname'=>array(self::BELONGS_TO, 'City', 'city'),
        );
    }

当我在评论表中有大约70条(或更多)评论时,出现错误:

When i have around 70 (or more) comments in Comment table, i have error:

Fatal error: Out of memory (allocated 348651520) (tried to allocate 78 bytes) in /home/milk/kolyasya.ru/diplomyii/framework/db/CDbCommand.php on line 516

这个问题的有趣之处在于,如果我注释with()的任何元素,例如:

The interesting part of this problem, is if i comment any element of with(), for example:

$model=User::model()->with('routes', 'likes', 'comments', /* 'questions' */, 'cityname')->findByPk($id);

然后一切正常运行.

我检查了所有模型中的所有关系,并设置了ini_set('memory_limit','512M'),但找不到问题的根源.

I checked all relations in all models and set ini_set('memory_limit', '512M'), but i can't find a source of the problem.

也许我需要使用延迟加载?

Maybe I need to use lazy loading?

推荐答案

行组合的数量激增.看看这个问题,它在较小规模上描述了相同的问题.基本上,您正在运行具有多个一对多联接的大型查询,类似于以下内容:

You're suffering from exploding number of row combinations. Take a look at this question, it describes the same problem on a smaller scale. Basically, you are running a huge query with multiple one-to-many joins, similar to this:

SELECT ... FROM `User` `t` 
  LEFT JOIN `Route` routes ON t.id = routes.author_id
  LEFT JOIN `Question` questions ON t.id = questions.author_id
  LEFT JOIN `Comment` comments ON t.id = comments.author_id
  LEFT JOIN `Like` likes ON t.id = likes.author_id
  LEFT JOIN `City` city ON t.city = city.id
  WHERE t.id = :id
  ORDER BY routes.id DESC, questions.id DESC, comments.id DESC, likes.id DESC

您可以使用此查询,将其修改为SELECT COUNT(*)并在phpMyAdmin中运行以查看它返回了多少行.它等于路线数量乘以问题数量乘以评论数量乘以数量喜欢由该用户创建.

You can take this query, modify it to SELECT COUNT(*) and run it in phpMyAdmin to see how many rows it returns. It will be equal to the number of routes multiplied by the number of questions multiplied by the number of comments multiplied by the number of likes created by this user.

在这种情况下,在单独的查询中获取每个HAS_MANY关系会更加高效. Yii可以做到:

In this situation, it would be a lot more efficient to fetch each HAS_MANY relation in a separate query. Yii can do that:

$model=User::model()
  ->with(array(
     'routes' => array('together' => false),
     'likes' => array('together' => false),
     'comments' => array('together' => false),
     'questions' => array('together' => false),
     'cityname' => array(),
  ))
  ->findByPk($id);

如果您这样做,Yii将改为以较少的内存使用量生成多个SQL查询,类似于以下内容:

If you do so, Yii will instead produce multiple SQL queries with less memory usage, similar to the following:

SELECT ... FROM `User` `t` 
  LEFT JOIN `City` `city` ON `t`.`city` = `city`.`id`
  WHERE `t`.`id` = :id;

SELECT ... FROM `Route` `routes`
  WHERE `author_id` = :id
  ORDER by `routes`.`id` DESC;

SELECT ... FROM `Question` `questions`
  WHERE `author_id` = :id
  ORDER BY `questions`.`id` DESC;

SELECT ... FROM `Comment` `comments`
  WHERE `author_id` = :id
  ORDER BY `comments`.`id` DESC;

SELECT ... FROM `Like` `likes`
  WHERE `author_id` = :id
  ORDER BY `likes`.`id` DESC;

结果将像以前一样汇总并返回到您的代码.

The results will be aggregated and returned to your code just like before.

这篇关于Yii渴望加载—致命错误:内存不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆