7

我有一個大的查詢(在我的查詢生成器)和大量的左連接。所以我得到文章與他們的評論和標籤等。 比方說,我有以下DQL:學說2:限制與左加入/分頁 - 最佳實踐

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

現在讓我們假設我的數據庫有超過100個相關博客文章,但我只希望在第10位,但與10的所有意見和所有的標籤,如果存在的話。 如果我使用setMaxResults,它會限制行數。所以我可能會得到前兩篇文章,但最後一篇文章缺少一些評論或標籤。所以下面的行爲不起作用。

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

使用勉強記載Pagination解決方案附帶doctrine2.2不爲我真正的工作要麼因爲它是如此之慢,我能以及加載的所有數據。

我嘗試了Stackoverflow Article中的解決方案,但即使該文章仍然缺少最佳實踐,並且呈現的解決方案速度很慢。

對於如何做到這一點,沒有最佳做法嗎? 沒有人在生產模式中使用Doctrine2.2?

+1

請將您的問題添加到您的問題中,甚至可以添加示例結果以顯示您想要的內容以及獲得的內容。 –

回答

10

用這樣的查詢獲得正確的結果是有問題的。在Doctrine網站上有一個教程來解釋這個問題。

Pagination

該教程是瞭解分頁,而不是獲得前5名成績,但總的想法是,你需要做一個「SELECT DISTINCT a.id從文章的一個... LIMIT 5」,而不是正常的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,您可以設置原則使用標量水化。

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

編輯在澄清問題的光:

你可以做你想做的事,在FROM子句這樣使用子查詢本地的MySQL:

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

然後看起來你需要做兩個查詢。我同意應該有一個更好的方法來限制和聯結連接的結果。 –