2012-10-01 16 views
14

यह वह जगह है django docs on the queryset iterator() method से:जब उपयोग करने के लिए या Django ORM में इटरेटर का उपयोग नहीं()

एक क्वेरीसमूह आम तौर पर उसके परिणामों आंतरिक रूप से कैश ताकि बार-बार मूल्यांकन अतिरिक्त प्रश्नों में परिणाम नहीं है। इसके विपरीत, इटेटरेटर() परिणाम परिणाम सीधे, क्वेरीज़ स्तर पर किसी भी कैशिंग के बिना पढ़ेगा (आंतरिक रूप से, डिफॉल टी इटेटर कॉलर इटेटर() और वापसी मूल्य कैश करता है)। एक प्रश्नोत्तरी के लिए जो बड़ी संख्या में ऑब्जेक्ट देता है जिन्हें आपको केवल एक बार पहुंचने की आवश्यकता होती है, इससे बेहतर प्रदर्शन और स्मृति में महत्वपूर्ण कमी हो सकती है।

पढ़ने के बाद, मैं अभी भी उलझन में हूं: बढ़ी हुई प्रदर्शन और स्मृति में कमी के बारे में बताता है कि हमें केवल iterator() विधि का उपयोग करना चाहिए। क्या कोई अच्छे और बुरे मामलों के कुछ उदाहरण iterator() उपयोग कर सकता है?

भले ही क्वेरी परिणाम कैश नहीं किए गए हैं, भले ही वे वास्तव में मॉडल को एक से अधिक बार एक्सेस करना चाहते हैं, तो क्या कोई ऐसा नहीं कर सकता है?

saved_queries = list(Model.objects.all().iterator()) 
+0

मुझे लगता है कि यह मॉडल आकार का मामला है ... यदि यह बड़ा है तो शायद आप स्मृति में चारों ओर एक गुच्छा लटकना नहीं चाहते हैं ... –

उत्तर

23

नोट वाक्य के पहले भाग तुम बाहर फोन: For a QuerySet which returns a large number of objects that you only need to access once

तो यह की बातचीत है: अगर आप की जरूरत है परिणामों के एक सेट का फिर से उपयोग, और वे इतनी के रूप में कई नहीं कर रहे हैं स्मृति समस्या का कारण बनने के लिए आपको iterator का उपयोग नहीं करना चाहिए। चूंकि अतिरिक्त डेटाबेस राउंड ट्रिप हमेशा कैश किए गए परिणाम का उपयोग करके आपके प्रदर्शन बनाम को कम करने जा रहा है।

आप अपने क्वेरीसमूह के लिए मजबूर कर सकता है एक सूची में से मूल्यांकन करने के लिए किया जा लेकिन:

  • यह सिर्फ saved_queries = Model.objects.all()
  • कहते हैं कि तुम एक वेब पेज पर परिणाम paginating कर रहे हैं और अधिक लिखना पड़ता है: आप में सभी परिणाम मजबूर कर दिया है जाएगा बाद के पेजिनेटर को 20 परिणामों के टुकड़े का चयन करने की अनुमति देने के बजाय मेमोरी (संभावित मेमोरी समस्याओं पर वापस)
  • , इसलिए आपके पास एक संदर्भ प्रोसेसर हो सकता है, उदाहरण के लिए, प्रत्येक प्रश्न के संदर्भ में क्वेरीरीसेट डालता है लेकिन जब आप इसे प्रमाण पत्र पर एक्सेस करते हैं तो केवल मूल्यांकन किया जाता है अनुरोधों में लेकिन यदि आपने मूल्यांकन किया है कि डेटाबेस हिट प्रत्येक अनुरोध होता है

ठेठ वेब ऐप केस अपेक्षाकृत छोटे परिणाम सेट के लिए है (उन्हें समय-समय पर ब्राउज़र में पहुंचाया जाना चाहिए, इसलिए अंकन या एक यदि आवश्यक हो तो डेटा वॉल्यूम कम करने के लिए समान तकनीक को नियोजित किया जाता है) इसलिए आमतौर पर मानक QuerySet व्यवहार वह है जो आप चाहते हैं। जैसा कि आपको कोई संदेह नहीं है, आपको कैशिंग का लाभ प्राप्त करने के लिए store the QuerySet in a variable होना चाहिए।

पुनरावर्तक का अच्छा उपयोग: प्रोसेसिंग परिणाम जो बड़ी मात्रा में उपलब्ध स्मृति (बहुत छोटी वस्तुओं या कम बड़ी वस्तुओं) लेते हैं। मेरे अनुभव में यह भारी डेटा प्रोसेसिंग करते समय अक्सर प्रबंधन कमांड में होता है।

0

मैं स्टीवन के साथ सहमत हैं और मैं एक अवलोकन किया था चाहते हैं:

  • "यह सिर्फ saved_queries = Model.objects.all() की तुलना में अधिक लिखना पड़ता है"।हां यह करता है लेकिन एक बड़ा अंतर है कि आपको सूची का उपयोग क्यों करना चाहिए (Model.objcts.all())। मैं आपको एक उदाहरण देता हूं, अगर आप इसे एक चर को सौंपा गया है, तो यह क्वेरी निष्पादित करेगा और इसे सहेजने से पहले, आइए कल्पना करें कि आपके पास + 1 एम रिकॉर्ड हैं, इसका मतलब है कि आपके पास एक सूची में + 1 एम रिकॉर्ड होंगे आप तुरंत बाद में उपयोग कर सकते हैं या नहीं कर सकते हैं, इसलिए मैं केवल स्टीवन के रूप में उपयोग करने की सिफारिश करता हूं, केवल Model.objects.all() का उपयोग करके, क्योंकि यह एक चर को असाइन किया गया है, यह तब तक निष्पादित नहीं होगा जब तक आप चर, कॉल को कॉल नहीं करते आप डीबी कॉल करते हैं।

  • आपको डीबी में कई कॉल करने से बचाने के लिए prefetch_related() का उपयोग करना चाहिए और इसलिए, यह आपको मदद करने और आपको बहुत समय बचाने के लिए django रिवर्स लुकअप का उपयोग करेगा।