2009-12-28 21 views
10

मैं ऐसी सेवा का निर्माण कर रहा हूं जिसे केस ट्रैकिंग सिस्टम की तरह कुछ बनाए रखने की आवश्यकता है। यहाँ हमारे मॉडल है:django प्रदर्शन?

class Incident(models.Model):  
    title = models.CharField(max_length=128) 
    category = models.ForeignKey(Category) 
    status = models.ForeignKey(Status)  
    severity = models.ForeignKey(Severity) 
    owned_by = models.ForeignKey(User, related_name="owned_by", null=True, blank=True) 
    next_action = models.ForeignKey(IncidentAction)  
    created_date = models.DateTimeField() 
    created_by = models.ForeignKey(User, related_name="opened_by")  
    last_edit_date = models.DateTimeField(null=True, blank=True) 
    last_edit_by = models.ForeignKey(User, related_name="last_edit_by", null=True, blank=True)   
    closed_date = models.DateTimeField(null=True, blank=True) 
    closed_by = models.ForeignKey(User, related_name="Closed by", null=True, blank=True) 

क्योंकि वहाँ विदेशी कुंजी का एक बहुत इस मॉडल में खींचा जा रहा हैं, यह दिलचस्प एसक्यूएल प्रश्नों के लिए बनाता है। हम djblets data grid और django डीबग टूलबार के परीक्षण के रूप में उपयोग कर रहे हैं, और हर बार जब हम एक विदेशी कुंजी का उपयोग करते हैं, तो यह देखने के लिए एक नया कॉलम जोड़ते हुए बहुत अधिक प्रश्नों पर हमला किया जाता है, यह मूल रूप से इस प्रकार की क्वेरी वर्कफ़्लो करता है :

#prepare the grid 
select * from incident_table; 
#render each row 
for each row in incident table 
    for each column that is a foreign key select row from foreign table with id 

यह प्रत्येक स्तंभ एक विदेशी कुंजी के लिए एक संपत्ति को खींचने के लिए कोशिश करता है के लिए पंक्ति प्रति एक अतिरिक्त चयन क्वेरी करता है।

मुझे लगता है कि यह प्रदर्शन के लिए विदेशी कुंजी मॉडल से गुणों को खींचने के संबंध में डीजेंगो और इसके ओआरएम के साथ एक सार्वभौमिक समस्या है। एक परीक्षण के रूप में, मैंने डेटा ग्रिड गिरा दिया और सिर्फ एक क्वेरीसेट के लिए गुणों की एक साधारण सूची की, और प्रश्नों को एक समान तरीके से गुब्बारा देखा।

हम मॉडल को मारने वाले बहुत से उपयोगकर्ताओं के साथ इसे स्केल करना चाहते हैं। तुलना के रूप में, मैंने उपयोगकर्ता मॉडल से एक समान दृश्य बनाया है, और इसका पूर्ण प्रदर्शन सिर्फ एक प्रश्न के साथ किया गया है क्योंकि यदि आप केवल दिए गए मॉडल से फ़ील्ड खींचते हैं, तो यह अतिरिक्त कॉलम प्रति अतिरिक्त डीबी हिट नहीं करता है।

कुछ अनुकूलन हम करने की कोशिश की थी:

  • django-orm-cache: Django 1.0.4 के साथ काम करने
  • django-caching प्रतीत नहीं करता है: यह कैशिंग के लिए अच्छी तरह से काम बहुधा मॉडलों के साथ
  • दृश्य स्तर कैशिंग पूछे memcached
  • संपादित करें: select_related() का उपयोग कर टेम्पलेट प्रतिपादन को गतिशीलता से वापस ले जा सकता है, लेकिन ऐसा लगता है कि यह विदेशी कुंजी का पालन करता है प्रति विदेशी कुंजी एकल प्रश्न का उपयोग कर मूल क्वेरीसेट पर समय का प्रमुख। बस समय से पहले बहु डेटाबेस क्वेरी हिट करने लगता है।

लेकिन वहाँ कुछ गहरे सवाल हम पर भीड़ का ज्ञान लिए अनुरोध कर रहे हैं: विदेशी कुंजी के टन के साथ

  • मॉडल के लिए, सबसे अच्छा तरीका यह कुशलतापूर्वक गुण प्राप्त करने के लिए क्वेरी बनाने के लिए क्या है विदेशी कुंजी से?
    • निर्भर मॉडल को उपरोक्त ओआरएम कैशिंग सिस्टम का उपयोग करने का एकमात्र तरीका कैश करना है?
    • या क्या यह ओआरएम को बढ़ाने का एक मानक मामला है और वांछित डेटाग्रिड आउटपुट को यथासंभव कुशलतापूर्वक प्राप्त करने के लिए जुड़ने के साथ अपनी खुद की कस्टम एसक्यूएल क्वेरी रोल करने की आवश्यकता है?

संबंधित प्रश्न हैं जो और कैशिंग पर चिंताओं विदेशी कुंजी उठाया:

DB/performance: layout of django model that rarely refers to its parent more than once, Django ORM: caching and manipulating ForeignKey objects:

उत्तर

11

select_related() सही समाधान है, आप इस बारे में गलत हैं कि इसे कैसे काम करना है। मुझे लगता है कि यदि आप अभी भी निर्दिष्ट एफके में एकाधिक प्रश्न प्राप्त कर रहे हैं तो आप select_related सही तरीके से उपयोग नहीं कर रहे हैं। एक अजगर सत्र का एक त्वरित लॉग (स्टूडियो है एक FK यहाँ django.auth.user के लिए):

>>> from django.db import connection 
>>> studios = Studio.objects.all().select_related('user') 
>>> for studio in studios: 
>>>  print studio.user.email 
>>>   
[email protected] 
[email protected] 
>>> len(connection.queries) 
1 

तो, मैं एक (2 अपने परीक्षण DB में) स्टूडियो वस्तुओं की सूची है और प्रत्येक के लिए उपयोगकर्ता मिला एक एसक्यूएल क्वेरी में से एक। Select_related() कॉल के बिना, इसमें तीन प्रश्न होते हैं।

ध्यान दें कि doesn't handle many-to-many relationships select_related - हालांकि मुझे लगता है कि आप मैन्युअल रूप से M2M के मध्यवर्ती तालिका क्वेरी अतिरिक्त क्वेरी की आवश्यकता के बिना उन FKS भी दिशा का पालन करने, जब तक कि आप मध्यवर्ती वस्तु से अपने क्वेरीसमूह शुरू करने के लिए ठीक हो सकता है। शायद यही आपको पकड़ रहा है? आपने केवल एफके रिश्ते निर्दिष्ट किए हैं, एम 2 एमएस नहीं, इसलिए मैंने इसका एक सरल उदाहरण दिया।

+0

आह, हाँ। मैं बहुत सही खड़ा हूं - ऐसा लगता है कि डेटाग्रिड वास्तव में आपूर्ति की गई क्वेरीसेट द्वारा प्रदान किए गए किसी भी अनुकूलन को अनदेखा कर रहा है और अपने स्वयं के लुकअप करता है। आपके उदाहरण के साथ मेरे मॉडल के स्वतंत्र परीक्षण ने दिन के रूप में स्पष्ट_संबंधित() के लाभ किए। धन्यवाद! – dmyung

संबंधित मुद्दे