7

मेरे पास एक बड़ी क्वेरी है (मेरे प्रश्न निर्माता में) और बहुत से बाएं जुड़ते हैं। इसलिए मुझे उनकी टिप्पणियों और टैग के साथ आलेख मिलते हैं।सिद्धांत 2: बाएं जॉइन/पेजिनेशन के साथ सीमित - सर्वश्रेष्ठ अभ्यास

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

अब मान लीजिए कि मेरी डेटाबेस में 100 से अधिक ब्लॉगपोस्ट है, लेकिन मैं केवल पहले 10 चाहते हैं, लेकिन उन सभी 10 की टिप्पणियों और उनके सभी टैग के साथ है, अगर वे मौजूद हैं: चलो कहते हैं कि मैं निम्नलिखित DQL करते हैं । यदि मैं setMaxResults का उपयोग करता हूं तो यह पंक्तियों को सीमित करता है। तो मुझे पहले दो पद मिल सकते हैं, लेकिन उनमें से आखिरी में से कुछ की टिप्पणियां या टैग गायब हैं। तो फॉलोइन काम नहीं करता है।

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

मुश्किल से प्रलेखित Pagination समाधान है कि doctrine2.2 साथ जहाजों वास्तव में मेरे लिए काम नहीं करता है का उपयोग करना या तो के बाद से यह इतनी धीमी गति से है, मैं साथ ही सभी डेटा लोड कर सकते हैं।

मैंने Stackoverflow Article में समाधानों की कोशिश की, लेकिन यहां तक ​​कि आलेख अभी भी एक सर्वोत्तम अभ्यास खो रहा है और प्रस्तुत समाधान घातक धीमा है।

क्या ऐसा करने के लिए कोई अच्छा अभ्यास नहीं है? कोई भी उत्पादन मोड में Doctrine2.2 का उपयोग नहीं कर रहा है?

+1

कृपया अपने प्रश्न के लिए कोड जोड़ें, शायद उदाहरण के साथ परिणाम जो आप चाहते हैं, और जो भी हो रहा है उसे दिखाने के लिए। –

उत्तर

10

इस तरह की क्वेरी के साथ उचित परिणाम प्राप्त करना समस्याग्रस्त है। इस समस्या को समझाते हुए सिद्धांत वेबसाइट पर एक ट्यूटोरियल है।

Pagination

ट्यूटोरियल बल्कि शीर्ष 5 परिणाम प्राप्त करने की तुलना में पृष्ठांकन के बारे में अधिक है, लेकिन कुल मिलाकर यह विचार है कि आप एक के बजाय "लेख एक ... सीमा 5 से अलग a.id का चयन करें" क्या करने की जरूरत है एक सामान्य चयन का। यह इससे थोड़ा अधिक जटिल है, लेकिन उस ट्यूटोरियल में अंतिम 2 अंक आपको सही रास्ते पर रखना चाहिए।

अद्यतन:

समस्या यहाँ सिद्धांत, या किसी अन्य ORM नहीं है। समस्या उन डेटाबेस को पूरी तरह से निहित करती है जो आप जिन परिणामों के लिए पूछ रहे हैं उन्हें वापस करने में सक्षम हैं। यह सिर्फ काम में शामिल हो जाता है।

यदि आप क्वेरी पर एक एक्सप्लिन करते हैं, तो यह आपको क्या हो रहा है इसके गहराई से जवाब देगा। इसके शुरुआती प्रश्न में इसके परिणाम जोड़ने का अच्छा विचार होगा।

पेजिनेशन आलेख में चर्चा की गई चीज़ों पर बिल्डिंग, ऐसा प्रतीत होता है कि आपको वांछित परिणाम प्राप्त करने के लिए कम से कम 2 प्रश्नों की आवश्यकता है। किसी क्वेरी में DISTINCT को जोड़ने से आपकी क्वेरी को नाटकीय रूप से धीमा करने की क्षमता होती है, लेकिन अगर आप इसमें शामिल होते हैं तो इसकी केवल आवश्यकता होती है। आप एक और प्रश्न लिख सकते हैं जो शामिल किए गए दिनांक द्वारा क्रमशः पहले 10 पदों को पुनः प्राप्त किए बिना प्राप्त करता है। एक बार आपके पास उन 10 पदों की आईडी हो जाने के बाद, अपने जुड़ने के साथ एक और क्वेरी करें, और WHERE blogpost.id IN (...) ORDER BY blogpost.created। यह विधि बहुत अधिक कुशल होना चाहिए।

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

के बाद से सभी आप पहली बार क्वेरी में के बारे में परवाह आईडी हैं, तो आप अदिश हाइड्रेशन का उपयोग करने के सिद्धांत सेट कर सकते हैं।

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

आप शायद एक सहसंबंधित सबक्वायरी का उपयोग करके एक प्रश्न में भी ऐसा कर सकते हैं। मिथक कि subqueries हमेशा बुरा है सच नहीं है। कभी-कभी वे जुड़ने से तेज़ होते हैं। आपको यह पता लगाने के लिए प्रयोग करना होगा कि आपके लिए सबसे अच्छा समाधान क्या है।

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 

जहाँ तक मुझे पता है, डीक्यूएल इस तरह की उपक्विरी का समर्थन नहीं करता है, इसलिए आप मूलभूत वर्ग का उपयोग कर सकते हैं।

+0

नहीं, मैं अपने एन का सबसे हालिया एम नहीं चाहता हूं। मैं अपने सभी एम, एक्स और वाई –

+0

के साथ सबसे हालिया एन चाहता हूं। मैं एक डीएबीएल/ओआरएम फ्रेमवर्क का उपयोग करने का एक बड़ा प्रशंसक नहीं हूं और फिर भी मूल का उपयोग कर रहा हूं क्वेरी। मुझे ज्यादा समझ में नहीं आता है। –

+1

फिर ऐसा लगता है कि आपको दो प्रश्न पूछने की आवश्यकता होगी। मैं सहमत हूं कि जुड़ने के पेज परिणामों को सीमित करने और पृष्ठ के बेहतर तरीके होने चाहिए। –