2010-05-24 19 views
10

मैं इन वस्तुओं के बारे में वस्तुओं और गुण स्टोर करने के लिए इस्तेमाल किया एक डेटाबेस है। गुणों की संख्या एक्स्टेंसिबल है, इस प्रकार आइटम मूल्य से जुड़ी प्रत्येक संपत्ति को स्टोर करने के लिए एक टेबल शामिल है। भंडारण के डेटा (चयन ITEM_ID और property_id उपयोग करते हुए) को पुन: प्राप्त, (जो पहली प्राथमिकता है और बहुत जल्दी हो गया है, मैं कई आवेषण (कुछ ही सेकंड में सैकड़ों) निष्पादित करना चाहते हैं):MySQL में बड़ी तालिका को कैसे संभालें?

CREATE TABLE `item_property` (
    `property_id` int(11) NOT NULL, 
    `item_id` int(11) NOT NULL, 
    `value` double NOT NULL, 
    PRIMARY KEY (`property_id`,`item_id`), 
    KEY `item_id` (`item_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

इस डेटाबेस दो गोल है (यह दूसरी प्राथमिकता है, यह धीमा हो सकता है लेकिन बहुत अधिक नहीं है क्योंकि यह डीबी के उपयोग को बर्बाद कर देगा)।

वर्तमान में यह तालिका 1.6 बिलियन प्रविष्टियों को होस्ट करती है और एक साधारण गणना में 2 मिनट तक लग सकते हैं ... सम्मिलन उपयोग करने योग्य नहीं है।

मैं अपने डेटा तक पहुंचने के लिए Zend_Db का उपयोग कर रहा हूं और यदि आप नहीं करते हैं तो मुझे कोई PHP पक्ष तत्व विकसित करने का सुझाव दें।

+0

प्रश्न वास्तव में php संबंधित नहीं है इसलिए मैंने इस टैग को हटा दिया – jigfox

+0

कोई समस्या नहीं जेन्स, आप सही हैं – AsTeR

उत्तर

10

आप कुछ कारणों के लिए एक समूह से अधिक विभिन्न डेटाबेस प्रबंधन प्रणालियों या विभाजन का उपयोग कर समाधान के लिए नहीं जा सकते हैं, वहाँ अभी भी तीन मुख्य बातें आप करने के लिए क्या मौलिक अपने प्रदर्शन में सुधार कर सकते हैं (और वे समूहों के साथ संयोजन में काम भी निश्चित रूप से):

  • सेटअप MyISAM भंडारण इंजन
  • उपयोग "डेटा लोड INFILE फ़ाइल नाम टेबल TableName में"
  • कई टेबल पर अपने डेटा को विभाजित

यही है। बाकी विवरण पढ़ें यदि आप विवरण में रुचि रखते हैं :)

अभी भी पढ़ रहे हैं? ठीक है, तो यहां जाता है: माईसाम कोने का पत्थर है, क्योंकि यह अब तक का सबसे तेज़ इंजन है। नियमित एसक्यूएल-कथन का उपयोग करके डेटा पंक्तियों को डालने के बजाय आपको उन्हें नियमित रूप से अंतराल पर फ़ाइल और insert that file में बैच करना चाहिए (जितनी बार आपको आवश्यकता होती है, लेकिन शायद ही कभी आपके आवेदन की अनुमति सबसे अच्छी होगी)। इस तरह आप प्रति मिनट दस लाख पंक्तियों के क्रम में सम्मिलित कर सकते हैं।

अगली चीज़ जो आपको सीमित करेगी वह आपकी कुंजी/अनुक्रमणिका है। जब वे आपकी स्मृति में फिट नहीं हो सकते हैं (क्योंकि वे बड़े होते हैं) तो आप दोनों प्रविष्टियों और प्रश्नों में एक बड़ी मंदी का अनुभव करेंगे। यही कारण है कि आप डेटा को कई तालिकाओं पर विभाजित करते हैं, सभी एक ही स्कीमा के साथ। एक समय में लोड होने पर आपकी तालिका को जितनी संभव हो सके उतनी बड़ी होनी चाहिए। सटीक आकार आपकी मशीन और निश्चित रूप से इंडेक्स पर निर्भर करता है, लेकिन कहीं 5 और 50 मिलियन पंक्तियों/तालिका के बीच होना चाहिए। यदि आप किसी अन्य के बाद पंक्तियों का एक बड़ा गुच्छा डालने के लिए उठाए गए समय को मापते हैं, तो आप इसे पा सकते हैं, जिस क्षण यह धीरे-धीरे धीमा हो जाता है। जब आप सीमा को जानते हैं, तो हर बार आपकी पिछली तालिका उस सीमा के करीब पहुंचने पर फ्लाई पर एक नई टेबल बनाएं।

बहु-समाधान का परिणाम यह है कि आपको कुछ डेटा की आवश्यकता होने पर केवल एक ही की बजाय अपने सभी टेबलों से पूछना होगा, जो आपके प्रश्नों को थोड़ा धीमा कर देगा (लेकिन यदि आप " केवल "एक अरब या तो पंक्तियां हैं)। जाहिर है यहां भी करने के लिए अनुकूलन हैं। यदि कुछ मौलिक है तो आप डेटा को अलग करने के लिए उपयोग कर सकते हैं (जैसे दिनांक, क्लाइंट या कुछ) आप इसे कुछ संरचित पैटर्न का उपयोग करके अलग-अलग तालिकाओं में विभाजित कर सकते हैं जो आपको यह बताता है कि कुछ प्रकार के डेटा टेबल के बिना पूछे बिना भी हैं। उस ज्ञान का उपयोग केवल उन तालिकाओं से पूछने के लिए करें जिनमें अनुरोधित डेटा आदि हो सकते हैं।

यदि आपको और भी ट्यूनिंग की आवश्यकता है, तो partitioning के लिए जाएं, जैसा कि ईनेकी और ओडो द्वारा सुझाया गया है।

इसके अलावा, आपको पता चलेगा कि यह सब जंगली अटकलें नहीं हैं: मैं इस समय अपने स्वयं के डेटा पर कुछ स्केलेबिलिटी परीक्षण कर रहा हूं और यह दृष्टिकोण हमारे लिए चमत्कार कर रहा है। हम हर दिन लाखों पंक्तियों को सम्मिलित करने के लिए प्रबंधन कर रहे हैं और प्रश्न ~ 100 एमएस लेते हैं।

+0

Rock'n'roll यह सबसे पूरा लगता है!मैं "लोड डेटा इन्फाइल" का प्रयास नहीं करूंगा, मेरे पास PHP पक्ष पर कोड को फिर से लिखने की कोई इच्छा नहीं है, और इससे मुझे ऐसा करने के लिए मजबूर किया जाएगा। मैं पार्टिशनिंग चीजों और इंजन को बदलकर मैसाइम में बदल रहा हूं। – AsTeR

+0

5.0 से 5.1 तक अपडेट करने से मुझे पहला प्रदर्शन सुधार मिलता है। मैंने पहली बार सभी विदेशी कुंजी हटा दी और 20 विभाजन का उपयोग किया। सभी गुणों (परीक्षण 1) प्राप्त करने के लिए एक सरल चयन: 0,7 सेकंड से 0,37 तक जाता है। सभी वस्तुओं की एक गणना (परीक्षण 2) एक से अधिक मिनट से 11 सेकंड तक जाती है। मैं तो testest 200 विभाजन: परीक्षण 1: 0,29 रों परीक्षण 2: 14,86 रों अंत में मैं 50 पार्टिशनों इस्तेमाल किया, MyISAM के लिए बदल गया है और सूचकांक हटाया: परीक्षण 1: 0,24 रों परीक्षण 2: <0,01 एस सभी को धन्यवाद! – AsTeR

0

सबसे पहले इनो डीबी का उपयोग न करें क्योंकि आपको माईसाम (लॉकिंग, लेनदेन इत्यादि) पर इसकी मुख्य विशेषता की आवश्यकता नहीं है। तो माईसाम का उपयोग करें, यह पहले से ही कुछ अंतर करेगा। तो अगर है कि अभी भी काफी तेजी से नहीं है, कुछ अनुक्रमण में मिलता है, लेकिन आप पहले से ही एक कट्टरपंथी फर्क देखना चाहिए।

+1

MyISAM अच्छी तरह से गति पर भी InnoDB से * बदतर * हो सकता है। यदि वे अपडेट एक साथ आ रहे हैं, तो माईसाम के टेबल-स्तरीय लॉकिंग का नकारात्मक नकारात्मक प्रभाव होने की संभावना है। – bobince

0

वाह, वह यह है कि काफी बड़ी मेज :)

अगर आप तेजी से होने के लिए भंडारण की जरूरत है, तो आप बैच अपने आवेषण सकता है और उन्हें एक ही कई सम्मिलित बयान के साथ सम्मिलित करें। हालांकि यह निश्चित रूप से अतिरिक्त क्लाइंट-साइड (PHP) कोड की आवश्यकता होगी, क्षमा करें!

INSERT INTO `table` (`col1`, `col2`) VALUES (1, 2), (3, 4), (5, 6)... 

किसी भी इंडेक्स को भी अक्षम करता है जिसकी आपको आवश्यकता नहीं है क्योंकि इंडेक्स कमांड कमांड को धीमा कर देता है। linky मेम्कैश में

+0

विचार अच्छा है, लेकिन मैं इसका परीक्षण करने के लिए ज़ेंड_Db का आनंद ले रहा हूं। – AsTeR

0

देखो देखने के लिए जहां यह लागू किया जा सकता:

वैकल्पिक रूप से आप अपनी मेज विभाजन को देखो सकता है। टेबल आकार/इंडेक्स को छोटा रखने के लिए क्षैतिज विभाजन में भी देखें।

+0

मैंने पहले से ही memcache का उपयोग किया है ... यह मेरी आवश्यकताओं के अनुरूप नहीं है। मेरे पास कैश करने के लिए कुछ भी नहीं है। मैं लंबे समय तक डेटा स्टोर करता हूं और फिर उन्हें प्रीप्रोसेस्ड पुनर्प्राप्त करता हूं। – AsTeR

0

पहला: 1.6 बिलियन प्रविष्टियों वाली एक तालिका इतनी बड़ी है। मैं कुछ सुंदर भारी लोड सिस्टम पर काम करता हूं जहां लॉगिंग टेबल भी सभी कार्यों का ट्रैक रखती है, यह वर्षों से अधिक नहीं मिलती है। तो यदि संभव हो, तो सोचें, अगर आप एक अधिक इष्टतम भंडारण विधि पा सकते हैं। मुझे आपकी सलाह नहीं मिल सकती क्योंकि मुझे आपकी डीबी संरचना नहीं पता है, लेकिन मुझे यकीन है कि अनुकूलन के लिए बहुत सारे कमरे होंगे। 1.6 बिलियन प्रविष्टियां बहुत बड़ी हैं।

प्रदर्शन पर कुछ बातें:

आप रेफेरेंन्शिअल सत्यनिष्ठा की जाँच करता है, जो की संभावना नहीं है की जरूरत नहीं है, तो आप MyISAM भंडारण इंजन के लिए स्विच कर सकते हैं। यह थोड़ा तेज़ है लेकिन अखंडता ckecks और लेनदेन की कमी है।

कुछ और के लिए, और अधिक जानकारी के लिए आवश्यक होगा।

+0

कुछ अन्य लोगों की तरह यहां कहा गया है, मैंने पढ़ा है कि माईसाम से यह तेज़ी से नहीं होगा, लेकिन मैं कोशिश करूंगा। – AsTeR

+0

जिस तरह से मैं किसी भी innoDB सुविधाओं का उपयोग नहीं कर रहा हूं – AsTeR

0

क्या आपने तालिका को partitioning का विकल्प माना है?

+0

नहीं, मेरे पास नहीं है और मुझे लगता है कि यह एक गंभीर अनुकूलन बिंदु हो सकता है। – AsTeR

-1

याद रखने की एक महत्वपूर्ण बात यह है कि MySQL की डिफ़ॉल्ट स्थापना इस तरह के भारी काम के लिए कॉन्फ़िगर नहीं है। सुनिश्चित करें कि आपके वर्कलोड के लिए आपके पास tuned it है।

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