2011-03-12 7 views
6

मैं पाइथन और MySQLdb का उपयोग कर MySQL क्वेरी चलाने के लिए थ्रेडेड क्लास का निर्माण कर रहा हूं। मुझे समझ में नहीं आ रहा है कि क्यों इन प्रश्नों को थ्रेड किया गया है उन्हें गैर-थ्रेडेड चलाने से धीमा है। यह दिखाने के लिए मेरा कोड यहां दिया गया है कि मैं क्या कर रहा हूं।मेरे थ्रेड किए गए MySQLdb प्रश्नों को पाइथन में समान गैर-थ्रेडेड प्रश्नों की तुलना में धीमे क्यों हैं?

सबसे पहले, यहां गैर-थ्रेडेड फ़ंक्शन है।

class queryThread(threading.Thread): 

    def __init__(self, queue): 
     threading.Thread.__init__(self) 
     self.queue = queue 

     self.db = MySQLdb.connect('localhost', 'user', 'pass', 'db_name') 
     self.cursor = self.db.cursor() 

    def run(self): 
     cur_query = self.queue.get() 
     self.cursor.execute(cur_query) 
     results = self.cursor.fetchall() 
     self.db.close() 
     self.queue.task_done() 

और यहाँ हैंडलर है::

def queryHandler(query_list): 
    queue = Queue.Queue() 

    for query in query_list: 
     queue.put(query) 

    total_queries = len(query_list) 
    for query in range(total_queries): 
     t = queryThread(queue) 
     t.setDaemon(True) 
     t.start() 

    queue.join() 

मुझे यकीन है कि क्यों इस थ्रेड कोड धीमी चल रहा है नहीं कर रहा हूँ

def testQueryDo(query_list): 

    db = MySQLdb.connect('localhost', 'user', 'pass', 'db_name') 
    cursor = db.cursor() 

    q_list = query_list 
    for each in q_list: 
     cursor.execute(each) 
     results = cursor.fetchall() 

    db.close() 

यहाँ मेरी थ्रेडेड क्लास है। दिलचस्प बात यह है कि यदि मैं एक ही कोड का उपयोग करता हूं, तो संख्याओं के अतिरिक्त कुछ सरल करें, थ्रेडेड कोड महत्वपूर्ण तेज है।

मैं समझता हूं कि मुझे कुछ पूरी तरह से स्पष्ट याद आना चाहिए, हालांकि किसी भी समर्थन की बहुत सराहना की जाएगी!

उत्तर

2

आप एन धागे शुरू कर रहे हैं, जिनमें से प्रत्येक MySQL से अपना कनेक्शन बनाता है, और आप थ्रेड को क्वेरी देने के लिए एक तुल्यकालिक कतार का उपयोग कर रहे हैं। एक प्रश्न प्राप्त करने के लिए प्रत्येक थ्रेड queue.get() (एक विशेष लॉक प्राप्त करना) पर अवरुद्ध कर रहा है, फिर डेटाबेस से कनेक्शन बना रहा है, और फिर task_done() पर कॉल कर रहा है जो अगली धागा आगे बढ़ने देता है। तो जबकि थ्रेड 1 काम कर रहा है, एन -1 थ्रेड कुछ भी नहीं कर रहे हैं। लॉक अधिग्रहण/रिलीज के इस ओवरहेड, साथ ही डेटाबेस के कई कनेक्शन बनाने और बंद करने के अतिरिक्त ओवरहेड जोड़ते हैं।

+0

इसके अलावा सीपीथॉन केवल एक थ्रेड को एक समय में चलाने की अनुमति देता है (जीआईएल के कारण) तो भी ... –

+0

आह, मैं इस धारणा के तहत था कि वे एक साथ चल रहे थे! धन्यवाद नमूनाबायस! यदि मैं प्रत्येक क्वेरी को फोर्क करने के लिए कई प्रक्रियाओं का उपयोग करता हूं, तो क्या यह अधिक कुशल होगा, या क्या मुझे याद आ रही थ्रेडिंग के साथ ऐसा करने का एक बेहतर/अधिक प्रभावी तरीका है? – mudda

+0

वास्तव में आपके आवेदन पर निर्भर करता है, लेकिन कुछ चीजें जो ऊपर दिए गए आपके उदाहरण के प्रदर्शन में सुधार लाती हैं: एक छोटे थ्रेडपूल का उपयोग करें और प्रत्येक थ्रेड के लिए प्रत्येक क्वेरी को कई क्वेरी वितरित करें, प्रत्येक थ्रेड कई क्वेरी के लिए अपने डेटाबेस कनेक्शन का पुन: उपयोग करें। यदि आप 'फोर्क' का उपयोग करने का निर्णय लेते हैं, तो आप अपने मल्टीप्रोसेसेस के साथ संवाद करना आसान बनाने के लिए [मल्टीप्रोसेसिंग] (http://docs.python.org/library/multiprocessing.html) मॉड्यूल को आजमा सकते हैं। – samplebias

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