2015-05-15 64 views
1

內加入我的doctrine2查詢增加執行時間從400毫秒至5秒,但如果我提取SQL和直接在SQLSERVER工作室運行需要幾毫秒執行。內我doctrine2查詢加入增加執行時間從400毫秒至5秒

下面

是我的查詢,瓶頸只是內部聯接:

$qb = $em->createQueryBuilder(); 
$q = $qb->select('wp.id, wp.last_activity_datetime') 
->from('\Entities\wall_post', 'wp') 
->LeftJoin('wp.wall_postsLikes', 'likes') 
->LeftJoin('wp.wall_postsShare', 'shares') 
->LeftJoin('wp.wall_postsComment', 'comments') 
->leftJoin('wp.wall_postsFrom_user','fromUser'); 
if($wall_type == self::WALL_TYPE_SOCIALISE) 
{ 
    $q->leftJoin('wp.wall_postsSocialise_album','album'); 
    $q->innerJoin('album.socialise_albumsSocialise_photo','photo'); 
} 
$q->setParameter('my_links_r', $my_links_r) 
->setParameter(1, $userId) 

->setFirstResult($offset) 
->setMaxResults($limit) 
->groupBy('wp.id, wp.last_activity_datetime') 
->orderBy('wp.last_activity_datetime', 'DESC'); 

if($wall_type) 
{ 
    $q->where('wp.wall_postsFrom_user = ?1 AND wp.wall_type = ?4'); 
    $q->orWhere('wp.wall_postsFrom_user IN (:my_links_r) AND wp.wall_type = ?4'); 
    $q->orWhere('likes.likesLiked_by IN (:my_links_r) AND wp.wall_type = ?4'); 
    $q->orWhere('shares.sharesShared_by IN (:my_links_r) AND wp.wall_type = ?4'); 
    $q->orWhere('comments.commentsIlook_user IN (:my_links_r) AND wp.wall_type = ?4'); 
    $q->andWhere('fromUser.account_closed_on is null'); 
    if($blocked_user_ids_arr): 
     $q->setParameter('blocked_users_r', $blocked_user_ids_arr); 
     $q->andWhere('wp.wall_postsFrom_user NOT IN (:blocked_users_r)'); 
    endif; 

    $q->setParameter(4, $wall_type); 
} 


$q = $q->getQuery()->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY); 

以下是我的SQL提取物,它運行夢幻與內部聯接也:

SELECT TOP 10 w0_.id AS id0, w0_.last_activity_datetime AS last_activity_datetime1 
FROM wall_post w0_ 
    LEFT JOIN likes l1_ ON w0_.id = l1_.wall_post_id 
    LEFT JOIN share s2_ ON w0_.id = s2_.wall_post_id 
    LEFT JOIN comments c3_ ON w0_.id = c3_.wall_post_id 
    LEFT JOIN ilook_user i4_ ON w0_.from_user_id = i4_.id 
    LEFT JOIN socialise_album s5_ ON w0_.socialise_album_id = s5_.id 
    INNER JOIN socialise_photo s6_ ON s5_.id = s6_.socialise_album_id 
WHERE ((w0_.from_user_id = 1 AND w0_.wall_type = 2) 
    OR (w0_.from_user_id IN (1) AND w0_.wall_type = 2) 
    OR (s2_.ilook_user_id IN (1) AND w0_.wall_type = 2)) 
    AND i4_.account_closed_on IS NULL 
GROUP BY w0_.id, w0_.last_activity_datetime 
ORDER BY w0_.last_activity_datetime DESC 

任何幫助,將不勝感激。

+0

你是100%肯定,你上面的代碼生成與底部的sql完全相同的SQL?你的album.socialise ...表有什麼樣的字段? –

+0

@JeremyC。是,僅從上述原則查詢中提取SQL。我的socialise_photo表具有1的主鍵(INT),2個其他整數字段和4 VARCHAR和1個日期時間字段。 –

回答

1

這是不準確的答案,但如果我使用具有聲明左的連接內加入代替解決了我的目的:

$q->leftJoin('album.socialise_albumsSocialise_photo','photo'); 
$q->having('count(photo) > 1'); 
+0

仍然在懷疑,爲什麼doctrine2內連接正在採取10倍更長的時間。 –