2013-09-24 6 views
11

के साथ Django ORM का खराब प्रदर्शन मैं ओरेकल बैकएंड के साथ एक Django वेबसाइट बना रहा हूं, और प्राथमिक कुंजी पर सरल लुकअप करते समय भी मैं बहुत धीमी प्रदर्शन का निरीक्षण करता हूं। MySQL में वही डेटा लोड होने पर एक ही कोड बहुत तेज़ काम करता है।ओरेकल

खराब प्रदर्शन का कारण क्या हो सकता है? मुझे संदेह है कि समस्या ओरेकल बाइंड पैरामीटर के उपयोग से संबंधित है, लेकिन यह मामला नहीं हो सकता है।

Django मॉडल (एक परीक्षण ~ 6,200,000 पंक्तियों के साथ तालिका)

from django.db import models 

class Mytable(models.Model): 
    upi = models.CharField(primary_key=True, max_length=13) 

    class Meta: 
     db_table = 'mytable' 

Django ORM (लेता है ~ 1s)

from myapp.models import * 
r = Mytable.objects.get(upi='xxxxxxxxxxxxx') 

बाँध मापदंडों साथ कच्चे क्वेरी (लेता है ~ 1 एस)

cursor.execute("SELECT * FROM mytable WHERE upi = %s", ['xxxxxxxxxxxxx']) 
row = cursor.fetchone() 
print row 

कोई बाँध के साथ कच्चे क्वेरी पैरामीटर (तात्कालिक)

cursor.execute("SELECT * FROM mytable WHERE upi = 'xxxxxxxxxxxxx'") 
row = cursor.fetchone() 
print row 

मेरे पर्यावरण

  • अजगर 2.6.6
  • Django 1.5.4
  • CX-ओरेकल 5.1.2
  • ओरेकल 11 जी

जब Oracle डाटाबेस से कनेक्ट कर रहा निर्दिष्ट करें:

'OPTIONS': { 
    'threaded': True, 
} 

किसी भी मदद की बहुत सराहना की जाएगी।

[अपडेट] मैं कुछ आगे की जांच के लिए Django डिबग टूलबार से debugsqlshell उपकरण का उपयोग किया था।

# takes ~1s 
>>>Mytable.objects.get(upi='xxxxxxxxxxxxx') 
SELECT "Mytable"."UPI" 
FROM "Mytable" 
WHERE "Mytable"."UPI" = :arg0 [2.70ms] 

यह है कि Django ओरेकल बाँध पैरामीटर का उपयोग करता है, और क्वेरी ही बहुत तेजी से है, लेकिन इसी अजगर वस्तु बनाने के लिए एक बहुत लंबा समय लगता है पता चलता है।

बस पुष्टि करने के लिए, मैंने cx_Oracle का उपयोग करके एक ही क्वेरी चलाई (ध्यान दें कि cursor मेरे मूल प्रश्न में Django cursor है)।

import cx_Oracle 
db= cx_Oracle.connect('connection_string') 
cursor = db.cursor() 

# instantaneous 
cursor.execute('SELECT * from mytable where upi = :upi', {'upi':'xxxxxxxxxxxxx'}) 
cursor.fetchall() 

Django ORM को धीमा कर सकता है क्या?

[अपडेट 2] हमने ओरेकल पक्ष से डेटाबेस प्रदर्शन देखा, और यह पता चला कि क्वेरी का उपयोग तब नहीं किया जाता जब क्वेरी Django से आती है। कोई विचार क्यों यह मामला हो सकता है?

+0

आप देखने क्षेत्र के लिए सूचकांक जाँच किया DB में मौजूद

यहाँ कुछ उपयोगी चर्चा थ्रेड कि मुझे मदद की कर रहे हैं? – esauro

+0

जब मैं SQL डेवलपर में तालिका का निरीक्षण करता हूं, तो मुझे लगता है कि उस कॉलम पर एक मान्य सामान्य अनुक्रमणिका है। – apetrov

+0

क्या होता है यदि आप SQL डेवलपर में 2 संस्करण चलाते हैं, और क्या क्वेरी योजना अलग-अलग हैं (योजना योजना या ऑटोट्रेस बटन का उपयोग करें)? बाइंड वैरिएबल के लिए 'SELECT * mytable से चुनें जहां upi =: s' और SQL डेवलपर आपको मान के लिए संकेत देगा। –

उत्तर

1

हमारे डीबीए के साथ काम करने के बाद, यह पता चला कि किसी कारण से Django get(upi='xxxxxxxxxxxx') क्वेरी डेटाबेस डेटाबेस का उपयोग नहीं किया था।

जब एक ही क्वेरी को filter(upi='xxxxxxxxxxxx')[:1].get() का उपयोग करके फिर से लिखा गया था, तो क्वेरी तेज थी।

get क्वेरी केवल पूर्णांक प्राथमिक कुंजी के साथ तेज थी (यह मूल प्रश्न में स्ट्रिंग थी)।

अंतिम समाधान

create index index_name on Mytable(SYS_OP_C2C(upi)); 

वहाँ चरित्र cx_Oracle और Oracle द्वारा इस्तेमाल किया सेट के बीच कुछ बेमेल हो रहा है। सी 2 सी सूचकांक जोड़ना समस्या को हल करता है।

अद्यतन: इसके अलावा, Oracle में VARCHAR2 से NVARCHAR2 का उपयोग करने जा ही प्रभाव पड़ता है और कार्यात्मक सूचकांक के बजाय प्रयोग किया जा सकता है। http://comments.gmane.org/gmane.comp.python.db.cx-oracle/3049 http://comments.gmane.org/gmane.comp.python.db.cx-oracle/2940

2

TO_CHAR(character) का उपयोग करते हुए प्रदर्शन मुद्दे को हल करना चाहिए::

cursor.execute("SELECT * FROM mytable WHERE upi = TO_CHAR(%s)", ['xxxxxxxxxxxxx'])