2009-05-11 6 views
11

मेरे पास एक अद्वितीय स्ट्रिंग फ़ील्ड और कुछ पूर्णांक फ़ील्ड के साथ डेटाबेस तालिका है। स्ट्रिंग फ़ील्ड आमतौर पर 10-100 वर्ण लंबा होता है।एक टेबल (MySQL, पायथन, Django) में हजारों रिकॉर्ड डालने का सबसे प्रभावी तरीका क्या है

एक बार हर मिनट या तो मेरे पास निम्न परिदृश्य है: मुझे तालिका की रिकॉर्ड संरचना से संबंधित 2-10 हजार टुपल्स की एक सूची प्राप्त होती है, उदा।

[("hello", 3, 4), ("cat", 5, 3), ...] 

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

मेरे कोड वर्तमान में इस सूची के माध्यम से दोहराता है, प्रत्येक टपल के लिए उपयुक्त मान के साथ एक पायथन मॉड्यूल वस्तु बनाता है, और कहता है ".save()", तो कुछ इस तरह:

@transaction.commit_on_success 
def save_data_elements(input_list): 
    for (s, i1, i2) in input_list: 
     entry = DataElement(string=s, number1=i1, number2=i2) 
     entry.save() 

इस कोड को वर्तमान में से एक है मेरे सिस्टम में प्रदर्शन बाधाओं का, इसलिए मैं इसे अनुकूलित करने के तरीकों की तलाश में हूं।

उदाहरण के लिए, मैं 100 टुपल्स ("हार्ड-कोडेड" एसक्यूएल में) के लिए एक INSERT कमांड वाले SQL कोड उत्पन्न कर सकता हूं और इसे निष्पादित कर सकता हूं, लेकिन मुझे नहीं पता कि यह कुछ भी सुधार करेगा या नहीं।

क्या आपके पास ऐसी प्रक्रिया को अनुकूलित करने के लिए कोई सुझाव है?

धन्यवाद

+0

अच्छा सवाल! तो, सबसे अच्छा जवाब एक पाठ फ़ाइल बनाने या स्ट्रिंग concatenation के माध्यम से एक एसक्यूएल क्वेरी उत्पन्न करने के लिए प्रतीत होता है? यह थोड़ा असंतुष्ट है! – JAL

उत्तर

11

आप प्रारूप "फ़ील्ड 1", "field2", में एक फाइल करने के लिए पंक्तियों में लिख सकते हैं .. और फिर डेटा लोड का उपयोग उन्हें

data = '\n'.join(','.join('"%s"' % field for field in row) for row in data) 
f= open('data.txt', 'w') 
f.write(data) 
f.close() 

लोड करने के लिए फिर इस पर अमल:

LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table; 

Reference

+0

जब तक डाटाबेस सर्वर पर कोड चल रहा है, तब तक लोड डेटा स्थानीय इन्फ्लू होना आवश्यक होगा। – staticsan

+0

इसके अलावा, लोड होने से पहले इंडेक्स अक्षम करें, और उसके बाद उन्हें सक्षम करें (इंडेक्स बनाने के लिए कुछ समय लगेगा)। यह नहीं देखा है कि यह Django आवेषण के साथ भी मदद करता है। – pufferfish

12

माईएसक्यूएल के लिए विशेष रूप से, डेटा लोड करने का सबसे तेज़ तरीका LOAD DATA INFILE का उपयोग कर रहा है, इसलिए यदि आप डेटा को प्रारूप में परिवर्तित कर सकते हैं, तो यह शायद इसे टेबल में लाने का सबसे तेज़ तरीका हो।

+0

एकमात्र संभावित समस्या बचत() विधि को ओवरराइड कर रही है। यदि आप ऐसा करते हैं, तो आपको अपने डिजाइन के बारे में दो बार सोचना होगा। –

+0

@ एसएलओटी: "सेव()" ओवरराइडिंग से आपका क्या मतलब है? क्या आपका मतलब है कि क्या मैं मॉड्यूल क्लास में .save() विधि को ओवरराइड करता हूं ताकि "लोड डेटा इन्फाइल" में खोए गए कोड के माध्यम से सहेजते समय पूर्व/पोस्ट प्रोसेसिंग कार्य हो रहे हों? यदि ऐसा है - यह मामला नहीं है, मैं ओवरराइड नहीं कर रहा हूं। सेव()। अन्यथा कृपया विस्तृत करें ... धन्यवाद –

4

आप LOAD DATA INFILE नहीं करते हैं के रूप में अन्य सुझावों में से कुछ का उल्लेख है, दो बातें आप तेजी लाने के लिए अपने आवेषण हैं कर सकते हैं:

  1. उपयोग विवरण तैयार - इस एसक्यूएल पार्स करने की भूमि के ऊपर बाहर कटौती हर डालने के लिए
  2. एकल लेन-देन में आपके निवेशनों को देखें करो - यह एक डीबी इंजन है कि समर्थन करता है, लेन-देन (InnoDB) की तरह
  3. का उपयोग कर की आवश्यकता होगी
+0

@ सेन: धन्यवाद, "तैयार बयान" से आपका मतलब है कि एसक्यूएल कोड कई% s तत्वों के साथ है जो मैं स्ट्रिंग/संख्याओं की सूची प्रदान करके बस "भरता हूं"? साथ ही, कृपया मेरे कोड (प्रश्न के शरीर में) पर एक नज़र डालें - अगर मैं सही ढंग से समझता हूं तो मैं पहले से ही एक लेनदेन का उपयोग कर रहा हूं @ banking.commit_on_success सजावट (मैं इनो डीबी का उपयोग कर रहा हूं) –

+0

मैं वास्तव में नहीं हूं निश्चित रूप से Django के साथ दृश्यों के पीछे क्या चल रहा है - मैं बस MySQL का उपयोग करने की एक सामान्य पृष्ठभूमि से आ रहा हूं, इसलिए मुझे नहीं पता कि लेनदेन के संबंध में यह क्या कर रहा है। तैयार बयानों के लिए - ऐसा लगता है कि यह आपके डेटा एलीमेंट ऑब्जेक्ट्स का कार्यान्वयन विवरण है। एक तैयार कथन होगा: 'stmt = तैयार करें (वर्गमीटर); stmt.execute (var1, var2 ..) 'db.execute (sqlStatement, var1, var2 ...) 'के बजाय' - यह हर बार पार्सिंग के बजाए नियमित अभिव्यक्तियों को संकलित करने जैसा है। –

4

यदि आप एक हाथ से लुढ़का INSERT कथन कर सकते हैं, तो मैं जिस तरह से जाऊंगा। एकाधिक मूल्य खंडों वाला एक INSERT कथन व्यक्तिगत INSERT कथनों की तुलना में बहुत तेज़ है।

+1

@staticsan: क्या आपको लगता है कि इस तरह के बयान के लिए कोई "व्यावहारिक" सीमा है? यानी मैं डेटाबेस को 10k पंक्तियों के साथ एक एकल INSERT क्वेरी भेज सकता हूं? –

+0

केवल वास्तविक सीमा नेटवर्क बफर का आकार है। इसका डिफ़ॉल्ट मान कई वर्षों तक 1 एमबी था, लेकिन कई लोगों ने इसे अधिकतम 16 एमबी तक बढ़ा दिया। MySQL के हाल के संस्करण भी बड़े पैकेट आकार का समर्थन कर सकते हैं। – staticsan

+1

यह रिकॉर्ड की संख्या की तुलना में पैकेट आकार के बारे में अधिक है। जैसे ही आप अपना सम्मिलित बफर बनाते हैं, ऐसा करने पर और अधिक नहीं जोड़ें यदि ऐसा करने से बफर को अधिकतम mysql पैकेट आकार में रखा जाएगा। मैं कुछ बेंचमार्किंग करता हूं और देखता हूं कि लाभ कहां से शुरू हो रहा है। आप अपने MySQL सर्वर से इसके अधिकतम पैकेट आकार के लिए भी पूछ सकते हैं: mysql> @@ max_allowed_packet \ g: @@ max_allowed_packet \ 33554432 – Will

1

यह डीबी में डेटा के वास्तविक भार से असंबंधित है, लेकिन ...

यदि "डेटा लोड हो रहा है ... प्रदान करना लोड हो जाएगा ... लोड जल्द ही किया जाएगा" उपयोगकर्ता को संदेश का प्रकार एक विकल्प है, तो आप एक अलग थ्रेड में INSERT या LOAD डेटा को असीमित रूप से चला सकते हैं।

बस कुछ और विचार करने के लिए।

+0

अधिक संभावना समस्या यह है कि सर्वर इस इनपुट को संसाधित करने में इतना व्यस्त है कि यह किसी अन्य अनुरोध को संभाल नहीं सकता । –

+0

मैं पहले से ही एक अलग धागे पर प्रसंस्करण कर रहा हूं (उपयोगकर्ता इसके खत्म होने की प्रतीक्षा नहीं कर रहा है), मेरी समस्या यह है कि कभी-कभी सिस्टम बहुत व्यस्त होता है, इसलिए एक मौका है कि कतार पर्याप्त सफाई के लिए अपने सफाई से तेज हो जाएगी समय ... –

2

सम्मिलित विधि के बावजूद, आप अधिकतम पढ़ने/लिखने की सहमति के लिए इनो डीबी इंजन का उपयोग करना चाहेंगे। माईसाम सम्मिलन की अवधि के लिए पूरी तालिका को लॉक कर देगा जबकि इनो डीडी (ज्यादातर परिस्थितियों में) केवल प्रभावित पंक्तियों को लॉक करेगा, जिससे चयन कथन आगे बढ़ने की अनुमति मिल जाएगी।

+0

धन्यवाद, मैंने एक स्पष्टीकरण जोड़ा कि मैं इनो डीबी का उपयोग कर रहा हूं –

1

मुझे सटीक विवरण नहीं पता है, लेकिन आप जेसन शैली डेटा प्रतिनिधित्व का उपयोग कर सकते हैं और इसे फिक्स्चर या कुछ के रूप में उपयोग कर सकते हैं। मैंने डगलस नेपोलियन द्वारा डीजेगो वीडियो वर्कशॉप पर कुछ ऐसा देखा। http://www.linux-magazine.com/online/news/django_video_workshop पर वीडियो देखें। और http://www.linux-magazine.com/online/features/django_reloaded_workshop_part_1। उम्मीद है कि यह मदद करता है।

आशा है कि आप इसे काम कर सकते हैं। मैंने अभी django सीखना शुरू किया है, इसलिए मैं आपको संसाधनों को इंगित कर सकता हूं।

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

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