2013-06-16 3 views
1

Yii 열심히로드하는 데 문제가 있습니다.Yii eager loading - 치명적인 오류 : 메모리 부족

$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 (또는 그 이상)의 코멘트 테이블에 의견이 때, 나는 오류가 있습니다

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()의 요소를 주석으로 처리하는 경우입니다. 예를 들면 다음과 같습니다.

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

모두 제대로 작동합니다.

모든 모델에서 모든 관계를 확인하고 ini_set ('memory_limit', '512M')을 설정했지만 문제의 원인을 찾을 수 없습니다.

게으른로드를 사용해야합니까?

+0

안녕하세요. 먼저이 로딩의 목표를 설명하십시오. 결과 페이지에서 무엇을 볼 수 있습니까? 댓글 카운터, 좋아요 등? 다른 페이지에 대한 링크가있는 카운터 일 수 있습니까? 즉, 사용자 의견의 ** 콘텐츠 ** 또는 ** ** 번호 **가 필요합니까? –

+0

내가 마지막 코멘트, 경로 등으로 탭을 가지고 있기 때문에 콘텐츠가 필요합니다. 나는 이것을 최적화 할 수있는 방법을 알고 있지만, (와) 관련된 테이블을 제거하면 왜 모든 것이 작동하는지 정말 흥미가 있습니다. –

+0

아마도 단일 사용자가 작성한 마지막 70 개의 주석을 표시해야 할 수도 있습니다. 따라서 관계를 재정의하고 제한을 추가하는 것이 좋습니다 (예 : 20) ... 그런 식으로, 필요한 물건 만 가져오고 전혀 사용하지 않을 물건이 없습니다. –

답변

0

행 조합 수가 폭발적으로 증가하고 있습니다. this question을보십시오, 더 작은 가늠자에 동일한 문제를 기술합니다. 기본적으로, 당신이에 일대 다 조인 여러 유사와 큰 쿼리를 실행하는 : 당신은 그것을 반환 행 수를보고,이 쿼리을 SELECT COUNT(*)로 수정하고 phpMyAdmin을에서 실행할 수 있습니다

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 

. 그것은 으로 질문의 수를 곱한 경로의 수하여 사용자가 만든 좋아하는의 수를 곱한 의견의 수를 곱한 동일 할 것이다. 이 상황에서


은 별도의 쿼리의 각 HAS_MANY 관계를 가져 오기 위해 훨씬 더 효율적으로 될 것입니다. 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 쿼리 :

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; 

결과가 집계되며처럼 코드에 반환 전에.

+0

감사합니다! 그레이트 대답)) –

+0

당신은 오신 것을 환영합니다. 도움이된다면 [이 답변을 수락 한 것으로 표시하십시오] (http://stackoverflow.com/help/someone-answers)하십시오. – DCoder