मैसकल: 1.4 बिलियन रिकॉर्ड पर इंडेक्स बनाएं


9

मेरे पास 1.4 बिलियन रिकॉर्ड के साथ एक तालिका है। तालिका संरचना इस प्रकार है:

CREATE TABLE text_page (
    text VARCHAR(255),
    page_id INT UNSIGNED
) ENGINE=MYISAM DEFAULT CHARSET=ascii

आवश्यकता स्तंभ पर एक सूचकांक बनाने के लिए है text

तालिका का आकार लगभग 34G है।

मैंने निम्नलिखित कथन द्वारा सूचकांक बनाने की कोशिश की है:

ALTER TABLE text_page ADD KEY ix_text (text)

10 घंटे के इंतजार के बाद आखिरकार मैंने इस दृष्टिकोण को छोड़ दिया।

क्या इस समस्या का कोई हल है?

अद्यतन : तालिका को अद्यतन या सम्मिलित या हटाए जाने की संभावना नहीं है। स्तंभ पर सूचकांक बनाने textका कारण यह है क्योंकि इस तरह की sql क्वेरी को अक्सर निष्पादित किया जाएगा:

SELECT page_id FROM text_page WHERE text = ?

अद्यतन : मैंने तालिका को विभाजित करके समस्या को हल किया है।

स्तंभ पर तालिका को 40 टुकड़ों में विभाजित किया गया है text। तब तालिका पर सूचकांक बनाने में लगभग 1 घंटे लगते हैं।

ऐसा लगता है कि तालिका आकार बहुत बड़ा हो जाने पर MySQL सूचकांक निर्माण बहुत धीमा हो जाता है। और विभाजन तालिका को छोटे चड्डी में कम कर देता है।


1
सामान्य CREATE INDEXकथन का उपयोग करने में क्या गलत है ?

मेरा सुझाव है कि यह प्रश्न सर्वरफॉल्ट पर बेहतर हो सकता है - यह प्रोग्रामिंग प्रश्न की तुलना में डीबी व्यवस्थापक से अधिक है।
therefromhere

@ डर्क: सामान्य क्री इंडेक्स दृष्टिकोण बहुत धीमा है। मुझे 1 दिन में कार्य पूरा करना है।

1
हम्म ... मुझे नहीं लगता कि आप इसके आसपास पहुँच सकते हैं। सूचकांक के निर्माण के लिए सभी रिकॉर्ड के माध्यम से स्कैन करने के लिए DBMS की आवश्यकता होती है, अपने "टेक्स्ट" फ़ील्ड्स को इकट्ठा करें और संबंधित ट्री नोड्स / उपप्रकारों को डालें / बदलें। और यह 34G के लिए ज्यादा समय लेता है ...
chiccodoro

आपके DB सर्वर में कितनी मेमोरी है? क्या आपने MySQL को उस सभी मेमोरी का उपयोग करने के लिए कॉन्फ़िगर किया है, या यह स्वयं को सीमित कर रहा है?

जवाबों:


4

क्या यह आपका सिस्टम हो सकता है बस कार्य तक नहीं है? मैं MySQL (यहां SQL सर्वर) का उपयोग नहीं करता हूं, लेकिन मुझे 800 मिलियन एंट्री टेबल इंडेक्सिंग का दर्द पता है। मूल रूप से .... आपको इसके लिए सही हार्डवेयर की आवश्यकता है (जैसे: बहुत तेज डिस्क)। अब मैं लगभग एक दर्जन वेलोसराप्टर्स का उपयोग करता हूं और प्रदर्शन बहुत अच्छा है;)

SQL सर्वर (MS SQL सर्वर के रूप में नहीं, लेकिन SQL का उपयोग करने वाले डेटाबेस सर्वर के रूप में) डिस्क एक्सेस के साथ रहते हैं और मर जाते हैं, और सामान्य डिस्क केवल बड़े ऑपरेशन के कार्य तक नहीं हैं।


मेरा संदेह यह है कि यदि रिकॉर्ड की संख्या छोटी है तो सूचकांक निर्माण आमतौर पर बहुत तेज़ है; कहो, लाखों। लेकिन जब गिनती अरबों में होती है तो सूचकांक निर्माण इतना धीमा हो जाता है। लगता है जैसे समय वृद्धि घातीय है।

वास्तव में नहीं होना चाहिए सामान्य रूप से MySQL की सीमाएँ हैं, लेकिन यह एक बकवास डेटाबेस नहीं है, और यह बहुत बुरा होगा। सूचकांक पीढ़ी धीमी हो जाती है, लेकिन लॉग (n), नहीं (n) से, इसलिए यह वास्तव में बुरा नहीं होना चाहिए।
टॉमटॉम

4

आप पाठ क्षेत्र के पहले (उदाहरण के लिए, 10) वर्णों पर एक इंडेक्स बनाना चाह सकते हैं।

डॉक्स से:

ऐसे सूचकांक बनाए जा सकते हैं जो स्तंभ मानों के केवल प्रमुख भाग का उपयोग करते हैं, अनुक्रमणिका उपसर्ग निर्दिष्ट करने के लिए col_name (लंबाई) सिंटैक्स का उपयोग करते हुए:

CREATE INDEX ix_text ON text_page (text(10))

4

मैंने तालिका को विभाजित करके समस्या को हल किया है।

स्तंभ पर तालिका को 40 टुकड़ों में विभाजित किया गया है text। तब तालिका पर सूचकांक बनाने में लगभग 1 घंटे लगते हैं।

ऐसा लगता है कि तालिका आकार बहुत बड़ा हो जाने पर MySQL सूचकांक निर्माण बहुत धीमा हो जाता है। और विभाजन तालिका को छोटे चड्डी में कम कर देता है।


तो 40 x 1 घंटा 10 घंटे से कम है?
सिम्बियन

3

सॉर्ट_बफ़र_साइज़ को 4GB पर सेट करें (या फिर आपके पास कितनी मेमोरी है इसके आधार पर)।

अभी क्रिएट इंडेक्स एक तरह का कर रहा है, लेकिन जब से आपके पास एक 32MB Sort_buffer_size है, यह मूल रूप से हार्ड ड्राइव को अनावश्यक रूप से जोर दे रहा है।


ये पोस्ट आपसे बहुत सीधे तौर पर असहमत हैं: xaprb.com/blog/2010/05/09/how-to-tune-mysqls-sort_buffer_size और बेहतर ronaldbradford.com/blog- ... यह लगता है कि यह वैश्विक मूल्य नहीं है, यह ऐसा है प्रति-क्वेरी, इसलिए यह 4GB प्रति क्वेरी है जिसकी आप अनुशंसा कर रहे हैं। इसके अलावा, जब यह 256K से अधिक हो जाता है तो यह वास्तविक इन-मेमोरी मेमोरी होने के बजाय डिस्क से मेम-मैप हो जाता है। यदि आप इसे छोटा रखते हैं तो इसके लिए कई पास की आवश्यकता होती है, लेकिन यह डिस्क से बचता है (यह स्वैप नहीं करता है)।
Ry4an Brase

3

यदि आपको प्रश्न बनाने की आवश्यकता नहीं है:

SELECT page_id FROM text_page WHERE text LIKE '?%';

मैं एक नया हैश स्तंभ बनाने और स्तंभ द्वारा तालिका को अनुक्रमित करने का सुझाव दूंगा। तालिका + अनुक्रमणिका का ऊपरी आकार बहुत छोटा हो सकता है।

UPD : वैसे, 1.4 बिलियन प्राथमिक कुंजी पूर्णांक 6 GB के बारे में हैं, जो कि स्ट्रिंग की औसत लंबाई 30 वर्णों से कम है, जो कि उपसर्ग पर अनुक्रमणित करना अधिक बेहतर हो सकता है।

आपको MERGE स्टोरेज इंजन पर भी नज़र डालनी चाहिए ।


2

ऐसा करने का एक तरीका सूचकांक सेट के साथ एक नई तालिका बनाना और डेटा को नई तालिका में कॉपी करना है।

इसके अलावा, सुनिश्चित करें कि आपके पास पर्याप्त अस्थायी स्थान है।


1
मैंने इस दृष्टिकोण की कोशिश की है। 10 घंटे के बाद 1% से कम डेटा नए टेबल पर कॉपी किया गया है।

1
यार ... यह 1.4 बिलियन रिकॉर्ड है। मिलियन नहीं, बिलियन। यह बहुत ज्यादा है। इसकी परवाह किए बिना थोड़ी देर लगने वाली है।

यदि आप इस विधि को करना पसंद करते हैं तो कॉपी को छोटे टुकड़ों में तोड़ दें। प्रत्येक प्रति के लिए 100 से 200 मिलियन के बारे में कहें।

1
@ विघटित, इसे छोटे टुकड़ों में तोड़ने से कुछ नहीं होगा (वास्तव में, यह इसे कम कुशल बना सकता है)। @ ब्रायन, 1.4 बिलियन रिकॉर्ड के साथ भी 1,000 घंटे नहीं लगने चाहिए।

0

यदि आप अभी भी सोच रहे हैं कि यह कैसे करना है, तो मैं आपको एक ऑनलाइन परिवर्तन तालिका उपकरण का उपयोग करने का सुझाव दूंगा।

इंटरनेट पर उनमें से बहुत सारे हैं, उनमें से एक प्रसिद्ध हैं:

हमारे पास बड़े टेबल (अधिक तब 500mil रिकॉर्ड) के साथ एक ही मुद्दे हैं और परिवर्तन एकदम सही है। यह एक नया tmp तालिका बनाता है, मूल तालिका पर ट्रिगर जोड़ता है (नए अपडेट / डिलीट / इंसर्ट रिकॉर्ड के लिए) और इस दौरान यह सभी रिकॉर्ड्स को नई तालिका (नई संरचना के साथ) कॉपी करता है

सौभाग्य!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.