MySQL

2009-09-22 17 views
40

में समग्र प्राथमिक कुंजी प्रदर्शन दोष हमारे पास एक समग्र प्राथमिक कुंजी वाली तालिका है जिसमें तीन फ़ील्ड शामिल हैं (और यह MySQL 5.1 में है)। इस टेबल पर करीब 200 आवेषण और प्रति सेकंड 200 चयन हैं, और तालिका का आकार लगभग 1 मिलियन पंक्तियां है और यह बढ़ रहा है।MySQL

मेरा प्रश्न है: क्या "समग्र प्राथमिक कुंजी" इस तालिका पर सम्मिलन और चयन के प्रदर्शन को कम करता है?

क्या मुझे समग्र प्राथमिक कुंजी के बजाय एक सरल ऑटो-इंकिंग आईएनटी आईडी फ़ील्ड का उपयोग करना चाहिए? (मुझे लगता है कि इस सवाल का जवाब बहुत ज्यादा रास्ते MySQL एकाधिक स्तंभों पर इंडेक्स हैंडल से संबंधित है)

उत्तर

50

INSERT और UPDATE प्रदर्शन थोड़ा भिन्न होता है: यह (INT) और (INT, INT) चाबी के लिए लगभग एक ही हो जाएगा।

SELECT समग्र PRIMARY KEY का प्रदर्शन कई कारकों पर निर्भर करता है।

यदि आपकी तालिका InnoDB है, तो तालिका को PRIMARY KEY मान पर पूरी तरह से क्लस्टर किया गया है।

इसका मतलब है कि दोनों मानों की खोज तेज होगी यदि दोनों मानों में कुंजी शामिल है: कोई अतिरिक्त कुंजी लुकअप की आवश्यकता नहीं होगी।

आपकी क्वेरी मान लिया जाये कि कुछ इस तरह है:

SELECT * 
FROM mytable 
WHERE col1 = @value1 
     AND col2 = @value2 

और तालिका लेआउट यह है:

CREATE TABLE mytable (
     col1 INT NOT NULL, 
     col2 INT NOT NULL, 
     data VARCHAR(200) NOT NULL, 
     PRIMARY KEY pk_mytable (col1, col2) 
) ENGINE=InnoDB 

, इंजन सिर्फ तालिका अपने आप में सही कुंजी मान देखने के लिए की आवश्यकता होगी।

आपको एक नकली आईडी के रूप में एक autoincrement क्षेत्र का उपयोग करते हैं:

CREATE TABLE mytable (
     id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
     col1 INT NOT NULL, 
     col2 INT NOT NULL, 
     data VARCHAR(200) NOT NULL, 
     UNIQUE KEY ix_mytable_col1_col2 (col1, col2) 
) ENGINE=InnoDB 

, तो इंजन, पहले की आवश्यकता होगी, सूचकांक ix_mytable_col1_col2 में (col1, col2) के मूल्यों देखने के लिए (सूचकांक से पंक्ति सूचक को पुनः प्राप्त id का मान) और तालिका में स्वयं id द्वारा एक और लुकअप बनाएं।

MyISAM टेबल के लिए, हालांकि, इससे कोई फर्क नहीं पड़ता है, क्योंकि MyISAM टेबल ढेर व्यवस्थित हैं और पंक्ति सूचक केवल फ़ाइल ऑफसेट है।

दोनों मामलों में, एक ही इंडेक्स बनाया जाएगा (PRIMARY KEY या UNIQUE KEY के लिए) और उसी तरह उपयोग किया जाएगा।

+0

+1। धन्यवाद, बहुत अच्छी तरह से समझाया। – Fr0zenFyr

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

यदि यह इनो डीबी है, तो समग्र प्राथमिक कुंजी प्रत्येक माध्यमिक अनुक्रमणिका में प्रत्येक प्रविष्टि में शामिल की जाएगी।

इसका मतलब है कि

  • आपका माध्यमिक अनुक्रमित अप के रूप में ज्यादा जगह उन स्तंभों + के रूप में सभी स्तंभों प्राथमिक एक माध्यमिक सूचकांक कुंजी
  • आप उपयोग कर सकते हैं में एक कवर सूचकांक अगर सभी स्तंभों के रूप में ले जाएगा आवश्यकता क्रमशः माध्यमिक सूचकांक + पी

ये निश्चित रूप से कर रहे हैं, एक नुकसान और एक लाभ में शामिल हैं।

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

बेशक

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

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

+0

कि क्या इसका मतलब यह है कि अगर मैं '(userId)', इस सूचकांक आंतरिक रूप से शामिल होंगे '(userId, reviewId, userId)' पर पर '(reviewId, userId)' और एक माध्यमिक सूचकांक मेरी प्राथमिक कुंजी है? – Benjamin

+0

@ बेंजामिन हां, आप सही हैं। यह स्पष्ट रूप से यहाँ कहा गया http://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html और इस पुस्तक में http://shop.oreilly.com/product/0636920022343.do –