Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

MySQL प्रदर्शन:एकल तालिका और विभाजन पर एकाधिक टेबल बनाम अनुक्रमणिका

20,000 टेबल बनाना एक बुरा विचार है। आपको बहुत पहले 40,000 टेबल की आवश्यकता होगी, और फिर और भी।

मैंने इस सिंड्रोम को मेटाडेटा ट्रिबल्स कहा है मेरी किताब में SQL Antipatterns . जब भी आप "टेबल प्रति एक्स" या "कॉलम प्रति एक्स" बनाने की योजना बनाते हैं, तो आप ऐसा हर बार देखते हैं।

यह वास्तविक प्रदर्शन समस्याओं का कारण बनता है जब आपके पास हजारों टेबल होते हैं। प्रत्येक तालिका को आंतरिक डेटा संरचनाओं, फ़ाइल डिस्क्रिप्टर, डेटा डिक्शनरी आदि को बनाए रखने के लिए MySQL की आवश्यकता होती है।

व्यावहारिक परिचालन परिणाम भी हैं। क्या आप वाकई एक ऐसा सिस्टम बनाना चाहते हैं जिसके लिए आपको हर बार एक नया उपयोगकर्ता साइन अप करने पर एक नई तालिका बनाने की आवश्यकता हो?

इसके बजाय, मेरा सुझाव है कि आप MySQL विभाजन का उपयोग करें। ।

तालिका को विभाजित करने का एक उदाहरण यहां दिया गया है:

CREATE TABLE statistics (
  id INT AUTO_INCREMENT NOT NULL,
  user_id INT NOT NULL,
  PRIMARY KEY (id, user_id)
) PARTITION BY HASH(user_id) PARTITIONS 101;

यह आपको एक तार्किक तालिका को परिभाषित करने का लाभ देता है, साथ ही जब आप विभाजन कुंजी के विशिष्ट मान के लिए क्वेरी करते हैं तो तालिका को कई भौतिक तालिकाओं में विभाजित करते हैं।

उदाहरण के लिए, जब आप अपने उदाहरण की तरह कोई क्वेरी चलाते हैं, तो MySQL केवल विशिष्ट user_id वाले सही विभाजन को एक्सेस करता है:

mysql> EXPLAIN PARTITIONS SELECT * FROM statistics WHERE user_id = 1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: statistics
   partitions: p1    <--- this shows it touches only one partition 
         type: index
possible_keys: NULL
          key: PRIMARY
      key_len: 8
          ref: NULL
         rows: 2
        Extra: Using where; Using index

विभाजन की HASH विधि का अर्थ है कि पंक्तियों को विभाजन में पूर्णांक विभाजन कुंजी के मापांक द्वारा रखा जाता है। इसका मतलब यह है कि एक ही विभाजन के लिए कई user_id का नक्शा, लेकिन प्रत्येक विभाजन में औसतन केवल 1/Nth जितनी पंक्तियाँ होंगी (जहाँ N विभाजन की संख्या है)। और आप तालिका को निरंतर विभाजनों के साथ परिभाषित करते हैं, इसलिए आपको हर बार एक नया उपयोगकर्ता मिलने पर इसका विस्तार करने की आवश्यकता नहीं है।

आप 1024 (या MySQL 5.6 में 8192) तक के किसी भी विभाजन को चुन सकते हैं, लेकिन कुछ लोगों ने इतना अधिक होने पर प्रदर्शन समस्याओं की सूचना दी है।

विभाजन की एक प्रमुख संख्या का उपयोग करने की सिफारिश की जाती है। यदि आपका user_id मान एक पैटर्न का पालन करता है (जैसे कि केवल सम संख्याओं का उपयोग करना), तो विभाजनों की अभाज्य संख्या का उपयोग करने से डेटा को अधिक समान रूप से वितरित करने में मदद मिलती है।

अपने सवाल कमेंट में दें:

एचएएसएच विभाजन के लिए, यदि आप 101 विभाजनों का उपयोग करते हैं जैसे कि मैं ऊपर दिए गए उदाहरण में दिखाता हूं, तो किसी दिए गए विभाजन में औसतन आपकी पंक्तियों का लगभग 1% होता है। आपने कहा था कि आपकी सांख्यिकी तालिका में 30 मिलियन पंक्तियाँ हैं, इसलिए यदि आप इस विभाजन का उपयोग करते हैं, तो आपके पास प्रति विभाजन केवल 300k पंक्तियाँ होंगी। MySQL के माध्यम से पढ़ने के लिए यह बहुत आसान है। आप अनुक्रमणिका का भी उपयोग कर सकते हैं (और करना चाहिए) -- प्रत्येक विभाजन का अपना सूचकांक होगा, और यह केवल 1% होगा जितना कि संपूर्ण अविभाजित तालिका पर सूचकांक होगा।

तो आप विभाजनों की उचित संख्या कैसे निर्धारित कर सकते हैं इसका उत्तर है:आपकी पूरी तालिका कितनी बड़ी है, और आप विभाजनों को औसतन कितना बड़ा बनाना चाहते हैं?

यदि आप HASH विभाजन का उपयोग करते हैं तो विभाजनों की संख्या बढ़ने की आवश्यकता नहीं है। आखिरकार आपके पास कुल 30 अरब पंक्तियां हो सकती हैं, लेकिन मैंने पाया है कि जब आपके डेटा की मात्रा परिमाण के क्रम से बढ़ती है, तो वैसे भी एक नई वास्तुकला की मांग होती है। यदि आपका डेटा इतना बड़ा हो जाता है, तो आपको संभवतः शार्डिंग . की आवश्यकता होगी एकाधिक सर्वरों के साथ-साथ एकाधिक तालिकाओं में विभाजित करना।

उस ने कहा, आप तालिका को ALTER TABLE के साथ फिर से विभाजित कर सकते हैं:

ALTER TABLE statistics PARTITION BY HASH(user_id) PARTITIONS 401;

इसके लिए तालिका का पुनर्गठन करना होगा (जैसे कि अधिकांश ALTER TABLE परिवर्तन), इसलिए उम्मीद करें कि इसमें कुछ समय लगेगा।

आप विभाजन में डेटा और अनुक्रमणिका के आकार की निगरानी करना चाह सकते हैं:

SELECT table_schema, table_name, table_rows, data_length, index_length
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE partition_method IS NOT NULL;

किसी भी तालिका की तरह, आप चाहते हैं कि सक्रिय अनुक्रमणिका का कुल आकार आपके बफ़र पूल में फ़िट हो जाए, क्योंकि यदि MySQL को SELECT क्वेरी के दौरान बफ़र पूल के अंदर और बाहर अनुक्रमणिका के कुछ हिस्सों को स्वैप करना है, तो प्रदर्शन प्रभावित होता है।

यदि आप RANGE या LIST विभाजन का उपयोग करते हैं, तो विभाजन जोड़ना, छोड़ना, विलय करना और विभाजित करना अधिक सामान्य है। देखें http://dev.mysql. com/doc/refman/5.6/hi/partitioning-management-range-list.html

मैं आपको विभाजन पर मैनुअल अनुभाग पढ़ने के लिए प्रोत्साहित करता हूं , और इस अच्छी प्रस्तुति को भी देखें:प्रदर्शन को बढ़ावा दें MySQL 5.1 पार्टिशन के साथ



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कॉलम के अनुसार PHP/MySQL समूह परिणाम

  2. PDO का उपयोग करके MySQL से परिणाम प्राप्त करें

  3. MySQL SIN () फ़ंक्शन - MySQL में किसी संख्या की साइन लौटाएं

  4. स्थानीय अनुक्रम विन्यास के लिए एक पर्यावरण चर का उपयोग करना

  5. % के स्थान पर MySQL में एक वर्ण का मिलान कैसे करें?