7

큰 쿼리 (내 쿼리 작성기에서)와 많은 왼쪽 조인이 있습니다. 그래서 나는 그들의 의견과 태그 등으로 기사를 얻는다. 존재하는 경우, 지금Doctrine2 : 왼쪽 조인/한정 매기기로 제한 - 모범 사례

$dql = 'SELECT blogpost, comment, tags 
FROM BlogPost blogpost 
LEFT JOIN blogpost.comments comments 
LEFT JOIN blogpost.tags tags'; 

의 내 데이터베이스가 100 개 이상의 블로그 게시물을 가지고 있지만 난 첫 번째 열을 원하는 가정 해 봅시다, 그러나 그 (10)의 모든 의견과 모든 태그 : 의 난 다음 DQL 있다고 가정 해 봅시다 . setMaxResults를 사용하면 행이 제한됩니다. 그래서 나는 처음 두 게시물을 얻을 수 있지만, 그 중 마지막 하나는 코멘트 또는 태그 중 일부가 누락되었습니다. 그래서 followin은 작동하지 않습니다. 너무 느린이기 때문에 doctrine2.2 함께 제공 정말 나를 위해 작동하지 않는 거의 문서화 Pagination 솔루션을 사용하여

$result = $em->createQuery($dql)->setMaxResults(15)->getResult(); 

중 하나, 나뿐만 아니라 모든 데이터를로드 할 수 있습니다.

Stackoverflow Article에서 솔루션을 사용해 보았지만이 기사에서도 모범 사례가 누락되어 제시된 솔루션이 매우 느립니다.

이 작업을 수행하는 가장 좋은 방법은 없습니까? 생산 모드에서 Doctrine2.2를 사용하는 사람이 있습니까?

당신은 FROM 절 등의 하위 쿼리를 사용하여 고유의 MySQL에서 당신이 원하는 것을 할 수 있습니다 : 정화 된 문제에 비추어

+1

질문에 대한 코드를 추가하십시오. 예를 들어 원하는 결과가 무엇인지, 그리고 무엇을 얻고 있는지 보여줄 수도 있습니다. –

답변

10

이와 같은 쿼리로 올바른 결과를 얻는 것은 문제가 있습니다. 이 문제를 설명하는 교리 문답 웹 사이트에 관한 튜토리얼이 있습니다.

Pagination

튜토리얼 오히려 상위 5 개 결과를 얻는 것보다 매김에 대한 자세한 내용을하지만, 전체적인 아이디어는 당신이 대신 "기사 ... LIMIT 5 구별 a.id 선택"을 할 필요가있다 정상 SELECT의. 이보다 조금 더 복잡하지만이 튜토리얼의 마지막 2 점은 당신을 올바른 방향으로 인도해야합니다.

업데이트 :

여기서 문제는 교리, 또는 다른 ORM 없습니다. 문제는 요청한 결과를 반환 할 수있는 데이터베이스에 있습니다. 이것은 조인이 작동하는 방식입니다.

쿼리에 EXPLAIN을 사용하면 발생하는 상황에 대한 심층적 인 대답을 얻을 수 있습니다. 초기 질문에 그 결과를 추가하는 것이 좋습니다.

페이지 매김 문서에서 설명한 내용을 바탕으로 원하는 결과를 얻으려면 최소 2 개의 쿼리가 필요합니다. DISTINCT를 쿼리에 추가하면 쿼리 속도가 크게 저하 될 수 있지만 조인이 필요한 경우에만 필요합니다. 조인없이 생성 된 날짜순으로 정렬 된 처음 10 개의 게시물을 검색하는 또 다른 쿼리를 작성할 수 있습니다. 10 개의 게시물 ID가 있으면 조인을 포함한 다른 쿼리를 실행하고 WHERE blogpost.id IN (...) ORDER BY blogpost.created입니다. 이 방법은 훨씬 더 효율적이어야합니다.

SELECT 
    bp 
FROM 
    Blogpost bp 
ORDER BY 
    bp.created DESC 
LIMIT 10 

첫 번째 쿼리에서 관심있는 것은 모두 ID이므로 Doctrine이 스칼라 수화를 사용하도록 설정할 수 있습니다.

SELECT 
    bg 
FROM 
    Blogpost bp 
LEFT JOIN 
    bp.comments c 
LEFT JOIN 
    bp.tags t 
WHERE 
    bp.id IN (...) 
ORDER BY 
    bp.created DESC 

아마도 상관 된 하위 쿼리를 사용하여 하나의 쿼리에서 수행 할 수 있습니다. 하위 쿼리가 항상 잘못된 신화는 사실이 아닙니다. 때로는 조인보다 빠릅니다. 가장 좋은 해결책이 무엇인지 알아 내려면 실험을해야합니다.

2

편집

SELECT * FROM 
(SELECT * FROM articles ORDER BY date LIMIT 5) AS limited_articles, 
comments, 
tags 
WHERE 
limited_articles.article_id=comments.article_id 
limited_articles.article_id=tags.article_id 

지금까지 내가 아는 한, DQL은 이와 같은 서브 쿼리를 지원하지 않으므로 NativeQuery 클래스를 사용할 수 있습니다.

+0

아니요, 가장 최근의 M이 내 N을 원하지 않습니다. 가장 최근의 N을 M, X 및 Y와 함께 모두 사용하고 싶습니다. –

+0

DABL/ORM 프레임 워크를 사용하고 기본 검색어. 나에게 많은 의미가 없다. –

+1

그러면 두 개의 쿼리를 만들어야합니다. 조인 결과를 제한하고 페이지하는 더 좋은 방법이 있어야한다는 것에 동의합니다. –