2013-08-29 2 views
0

symfony2 프로젝트에서 doctrine을 사용하고 있습니다.Doctrine Paginator Foreach 매우 느림

나는 테이블 이벤트와 테이블 사진이 있습니다. 하나의 이벤트는 하나 이상의 사진을 가질 수 있으며 사진은 하나의 이벤트와 관련됩니다. 여기

내 DQL 쿼리 중 하나입니다, 쿼리가 매우 느리게 (10 초 이상)이다 11500 이벤트 (160 개) 000 사진과 같이와

$dql = " 
    SELECT e, (e.views * 0.1) + (e.likes * 0.9) as ratingEvent 
    FROM WevseenMainBundle:Event e 
    INNER JOIN e.photos p 
    INNER JOIN e.firstPhoto fp 
    WHERE fp.date BETWEEN :dateA AND :dateB 
    AND p.lat BETWEEN :latA AND :latB 
    AND (p.lng > :lngA AND p.lng < :lngB) 
    AND e.status = 'open' 
    GROUP BY e 
    HAVING COUNT(p.id) >= :minCountPhotos 
    ORDER BY ratingEvent DESC 
    "; 

    $query = $em->createQuery($dql) 
    ->setParameters($parameters) 
    ->setFirstResult($firstEntry) // 0 
    ->setMaxResults($numberOf); // 10 

    $paginatorEvents = new Paginator($query, true); 

, 그것은

GROUP BY e 
HAVING COUNT(p.id) >= :minCountPhotos 
에서오고있다

없으면 빠릅니다.

은 내가 SF2 프로파일을 확인하고는 말한다 :

SELECT count(DISTINCT e0_.id) AS sclr0 FROM Event e0_ INNER JOIN Photo p1_ ON e0_.id = p1_.event_id INNER JOIN Photo p2_ ON e0_.firstPhoto_id = p2_.id WHERE p2_.date BETWEEN ? AND ? AND p1_.lat BETWEEN ? AND ? AND (p1_.lng > ? AND p1_.lng < ?) AND e0_.status = 'open' GROUP BY e0_.id, e0_.name, e0_.description, e0_.nb_photos, e0_.views, e0_.viewsEventPhotos, e0_.votes, e0_.rating, e0_.likes, e0_.up, e0_.down, e0_.status, e0_.end, e0_.time, e0_.averageTimeEvent, e0_.averageTimePhotos, e0_.averageTimeEventAndPhotos, e0_.needInstagramUpdate, e0_.origin, e0_.featured, e0_.firstPhoto_id HAVING COUNT(p1_.id) >= ? 
Parameters: [Object(DateTime), Object(DateTime), '-42.93442389074508', '73.48078267112892', '-180', '180', '2'] 

Time: 2029.33 ms 

    SELECT DISTINCT e0_.id AS id0, e0_.views * 1 + e0_.likes * 0 AS sclr1 FROM Event e0_ 
INNER JOIN Photo p1_ ON e0_.id = p1_.event_id INNER JOIN Photo p2_ ON e0_.firstPhoto_id = p2_.id WHERE p2_.date BETWEEN ? AND ? AND p1_.lat BETWEEN ? AND ? AND (p1_.lng > ? AND p1_.lng < ?) AND e0_.status = 'open' GROUP BY e0_.id, e0_.name, e0_.description, e0_.nb_photos, e0_.views, e0_.viewsEventPhotos, e0_.votes, e0_.rating, e0_.likes, e0_.up, e0_.down, e0_.status, e0_.end, e0_.time, e0_.averageTimeEvent, e0_.averageTimePhotos, e0_.averageTimeEventAndPhotos, e0_.needInstagramUpdate, e0_.origin, e0_.featured, e0_.firstPhoto_id HAVING COUNT(p1_.id) >= ? ORDER BY sclr1 DESC LIMIT 10 OFFSET 0 

Time: 6179.01 ms 

시간이 걸리는 두 쿼리가있다. 어떻게 개선 할 수 있습니까?

UPDATE, 해결 방법 :

당신이 매기기에 반복 경우에만 요청이 실행

GROUP BY e.id 
+0

아마도 foreach가 입력되었을 때만 처음으로 쿼리가 실행되기 때문에 쿼리가 실행됩니다. 쿼리는 8 초 걸립니다. – hakre

+0

나는 그것에 대해 생각했지만 약 11000 개의 이벤트와 160,000 장의 사진이 있고, 약간 과장된 8 초가 아닌가? – httpete

+0

흠, 내가 어떻게 대답해야합니까? 아마도 교리와 데이터베이스 사이에 서면 계약이있을 수 있으며, 수락 가능한 시간이 기록되어 있고 시간이 오래 걸리면 돈을 돌려 받거나 누군가를 고소 할 수 있습니까? : D 상황이 그들이 필요한 시간이 걸릴, 이것은 컴퓨터, 빌어 먹을 바보 만 할 일을했다. 나는이 기계들이 그들이 충분히 빠르지 않다는 것을 알려주는 감정이 없다고 생각하고, 속도를 내려고 노력한다. – hakre

답변

1

GROUP BY e 

을 변경했습니다. 번역 된 SQL 요청을 복사하여 Doctrine 외부에서 프로파일 링해야합니다. 실행하는 데 8 초가 걸릴 수 있습니다. 그리고 현명한 선택 인덱스를 테이블에 추가하면 훨씬 더 빠를 가능성이 있습니다.

+0

SQL로 번역 된 쿼리를 시도했는데 약 1 초가 걸렸습니다. – httpete

+0

모든 요청에 ​​대해? 쿼리 캐시가 없습니까? Doctrine은 이와 같은 페이지 매김에 대해 최대 3 개의 요청을 실행할 수 있다고 생각합니다. 하나는 전체 카운트 용이고 하나는 ID 용이고 다른 하나는 데이터 용입니다. – jchampion

+0

echo $ query-> getSQL();을 사용했습니다. 그리고 교리보다 10 배 빠릅니다 ... 너무 오래 걸리는 수화 일 수도 있습니다 – httpete