यह धीमा क्यों है :यदि आपने केवल दो ManyToMany फ़ील्ड द्वारा एनोटेशन . का उपयोग किया है फिर आप एक अवांछित इन सभी तालिकाओं का बड़ा जुड़ाव create बनाते हैं साथ में। मूल्यांकन की जाने वाली पंक्तियों के कार्टेशियन उत्पाद का आकार लगभग Have.objects.count() * Want.objects.count()
है . आपने तब लिखा था distinct=True
अंततः एक अवैध विशाल परिणाम प्राप्त न करने के लिए डुप्लिकेट किए गए आइटमों की संख्या को प्रतिबंधित करने के लिए।
पुराने Django के लिए ठीक करें:यदि आप केवल queryset.annotate(have_count=Count("have"))
का उपयोग करेंगे आपको distinct=True
. के बिना सही परिणाम जल्दी मिलेगा या एक ही परिणाम भी अलग के साथ तेजी से। फिर आप स्मृति में पायथन द्वारा दो प्रश्नों के परिणामों को जोड़ सकते हैं।
समाधान Django>=1.11 . में एक अच्छा समाधान संभव है (आपके प्रश्न के दो साल बाद) क्वेरी के साथ . का उपयोग करके दो उपप्रश्न , एक के लिए Have
और एक Want
. के लिए , सभी एक अनुरोध द्वारा, लेकिन सभी तालिकाओं को एक साथ मिलाने के लिए नहीं।
from django.db.models import Count, OuterRef, Subquery
sq = Collection.objects.filter(pk=OuterRef('pk')).order_by()
have_count_subq = sq.values('have').annotate(have_count=Count('have')).values('have_count')
want_count_subq = sq.values('want').annotate(have_count=Count('want')).values('want_count')
queryset = queryset.annotate(have_count=Subquery(have_count_subq),
want_count=Subquery(want_count_subq))
सत्यापित करें :आप str(my_queryset.query)
प्रिंट करके धीमी और स्थिर SQL क्वेरी दोनों की जांच कर सकते हैं कि यह ऊपर वर्णित अनुसार है।