एसक्यूएल प्राथमिक कुंजी और सूचकांक


106

मान लें कि मेरे पास प्राथमिक कुंजी के रूप में सेट किए गए डेटाबेस में एक आईडी पंक्ति (int) है। अगर मैं आईडी से क्वेरी करता हूं, तो क्या मुझे भी इसे इंडेक्स करने की जरूरत है? या यह एक प्राथमिक कुंजी होने का मतलब है कि यह पहले से ही अनुक्रमित है?

कारण मैं पूछ रहा हूं क्योंकि MS SQL सर्वर में मैं इस आईडी पर एक इंडेक्स बना सकता हूं, जैसा कि मैंने कहा था कि यह मेरी प्राथमिक कुंजी है।

संपादित करें: एक अतिरिक्त प्रश्न - क्या यह प्राथमिक कुंजी को अतिरिक्त रूप से अनुक्रमित करने के लिए कोई नुकसान पहुंचाएगा?

जवाबों:


73

आप सही हैं, यह भ्रामक है कि SQL सर्वर आपको उसी फ़ील्ड (ओं) पर डुप्लिकेट इंडेक्स बनाने की अनुमति देता है। लेकिन तथ्य यह है कि आप एक और बना सकते हैं कि पीके सूचकांक पहले से मौजूद नहीं है।

अतिरिक्त सूचकांक कोई अच्छा नहीं करता है, लेकिन एकमात्र नुकसान (बहुत छोटा) अतिरिक्त फ़ाइल आकार और पंक्ति-निर्माण ओवरहेड है।


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

50

जैसा कि बाकी सभी ने पहले ही कहा है, प्राथमिक कुंजी स्वचालित रूप से अनुक्रमित होती है।

प्राथमिक कुंजी स्तंभ पर अधिक अनुक्रमणिका बनाना केवल तभी समझ में आता है जब आपको प्राथमिक कुंजी और कुछ अन्य विशिष्ट स्तंभों का उपयोग करने वाली क्वेरी को अनुकूलित करने की आवश्यकता होती है। प्राथमिक कुंजी कॉलम पर और इसके साथ कुछ अन्य कॉलमों को शामिल करके, आप एक क्वेरी के लिए वांछित अनुकूलन तक पहुंच सकते हैं।

उदाहरण के लिए, आपके पास कई स्तंभों वाली एक तालिका है, लेकिन आप केवल आईडी, नाम और पते के स्तंभों की क्वेरी कर रहे हैं। ID को प्राथमिक कुंजी के रूप में लेते हुए, हम निम्नलिखित सूचकांक बना सकते हैं जो ID पर बनाया गया है लेकिन इसमें नाम और पता कॉलम शामिल हैं।

CREATE NONCLUSTERED INDEX MyIndex
ON MyTable(ID)
INCLUDE (Name, Address)

इसलिए, जब आप इस क्वेरी का उपयोग करते हैं:

SELECT ID, Name, Address FROM MyTable WHERE ID > 1000

SQL सर्वर आपको केवल आपके द्वारा बनाए गए इंडेक्स का उपयोग करके परिणाम देगा और यह वास्तविक तालिका से कुछ भी नहीं पढ़ेगा।


28

नोट: यह उत्तर एंटरप्राइज़-क्लास डेवलपमेंट को बड़े में संबोधित करता है ।

यह एक RDBMS मुद्दा है, न कि केवल SQL सर्वर, और व्यवहार बहुत दिलचस्प हो सकता है। एक के लिए, जबकि प्राथमिक कुंजी के लिए स्वचालित रूप से (विशिष्ट रूप से) अनुक्रमित होना आम है, यह पूर्ण नहीं है। ऐसे समय होते हैं जब यह आवश्यक होता है कि प्राथमिक कुंजी विशिष्ट रूप से अनुक्रमित न हो।

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

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

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

मैंने कई बार दो अरब पंक्तियों, 8 टीबी भंडारण, और प्रति दिन चालीस मिलियन पंक्ति आवेषण के रूप में तालिकाओं के साथ इस मुद्दे से निपटा है। मुझे इसमें शामिल सिस्टम को फिर से डिज़ाइन करने का काम सौंपा गया था, जिसमें स्टेप वन के रूप में व्यावहारिक रूप से अद्वितीय प्राथमिक कुंजी इंडेक्स को शामिल करना था। वास्तव में, उस सूचकांक को गिराना केवल एक आउटेज से उबरने के लिए उत्पादन में आवश्यक था, इससे पहले कि हम भी एक नया स्वरूप के करीब हो जाएं। उस रीडिज़ाइन में प्राथमिक कुंजी की विशिष्टता सुनिश्चित करने और डेटा तक त्वरित पहुँच प्रदान करने के अन्य तरीके शामिल थे।


क्या होगा यदि कुंजी एक int या bigint autoincrement कुंजी है? क्या SQL सर्वर इस मामले में एक अद्वितीय सूचकांक स्कैन नहीं करने के लिए पर्याप्त स्मार्ट है?
क्विलब्रेकर

1
@quillbreaker: एक IDENTITYक्षेत्र अद्वितीय होने की गारंटी नहीं है। सब के बाद, उपयोगकर्ता डुप्लिकेट मान सम्मिलित कर सकते हैं यदि वे उपयोगकर्ता IDENTITY_INSERT

मुझे पता है कि यह एक प्राचीन विषय है, लेकिन मुझे समझ में नहीं आता है कि सिस्टम पर एक इंडेक्स की विशिष्टता कैसे लोड होगी। B + ट्री स्कैन O (लॉग एन) * v होना चाहिए जहां v इंडेक्स विखंडन, अपूर्ण पेड़ संतुलन, आदि के लिए विवश ओवरहेड है। इस प्रकार 2 बिलियन पंक्तियों को लॉग बेस 2 होगा 2,000,000,000 (लगभग 31 साइक्स) बार, कहते हैं, 2 या 3 या यहां तक ​​कि 10. 40M आवेषण प्रति दिन लगभग 462 / सेकंड है, ~ 100 IO की प्रति प्रविष्टि ... आह ... ओह। समझा। और यह व्यापक एसएसडी से पहले था।
चार्ल्स बर्न्स

जब तक आप विशिष्टता की कमी को कम नहीं करते, तब तक अद्वितीयता के लिए प्रत्येक पंक्तियों की जाँच का ओवरहेड बहुत अधिक नहीं होगा?
मैक्स कैंडोसिया

20

प्राथमिक कुंजी हमेशा डिफ़ॉल्ट रूप से अनुक्रमित होती हैं।

SQL सर्वर प्रबंधन स्टूडियो या Transact-SQL का उपयोग करके आप SQL Server 2012 में प्राथमिक कुंजी परिभाषित कर सकते हैं। एक प्राथमिक कुंजी बनाने से स्वचालित रूप से एक संबंधित अद्वितीय, क्लस्टर किए गए या गैर-अनुक्रमित सूचकांक का निर्माण होता है।

http://technet.microsoft.com/en-us/library/ms189039.aspx


9

यहाँ MSDN से मार्ग :

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


8

जब तक आप गैर क्लस्टर नहीं निर्दिष्ट करते हैं, तब तक एक PK एक संकुल सूचकांक बन जाएगा


3

एक PRIMARY KEYया UNIQUEबाधा की घोषणा SQL सर्वर स्वचालित रूप से एक सूचकांक बनाने के लिए कारण बनता है।

एक अद्वितीय सूचकांक एक बाधा के मिलान के बिना बनाया जा सकता है, लेकिन एक अद्वितीय सूचकांक होने के बिना एक बाधा (या तो प्राथमिक कुंजी या अद्वितीय) मौजूद नहीं हो सकती।

यहाँ से, एक बाधा का निर्माण होगा:

  • एक ही नाम के साथ एक सूचकांक बनाया जा सकता है
  • इनकार किए गए सूचकांक को छोड़ने से इनकार किया जाता है क्योंकि बाधा इसके बिना मौजूद नहीं है

और एक ही समय में बाधा छोड़ने से संबंधित सूचकांक गिर जाएगा।

तो, क्या वास्तविक अंतर है PRIMARY KEYया UNIQUE INDEX:

  • NULLमानों की अनुमति नहीं है PRIMARY KEY, लेकिन UNIQUEअनुक्रमणिका में अनुमत है ; और सेट ऑपरेटर (UNION, EXCEPT, INTERSECT) की तरह, यहां NULL = NULLइसका मतलब है कि आपके पास दो के रूप में केवल एक ही मूल्य हो सकता हैNULL s एक दूसरे के डुप्लिकेट के रूप में जाते हैं;
  • 999PRIMARY KEY प्रति तालिका केवल एक ही मौजूद हो सकती है अद्वितीय अनुक्रमित बनाए जा सकते हैं
  • जब PRIMARY KEYबाधा बनती है, तो इसे तब तक क्लस्टर बनाया जाता है जब तक कि मेज पर पहले से ही एक क्लस्टर इंडेक्स न हो या NONCLUSTEREDइसकी परिभाषा में उपयोग किया जाता हो; जब UNIQUEसूचकांक बनाया जाता है, तो इसे NONCLUSTEREDतब तक बनाया जाता है जब तक कि यह विशिष्ट न हो CLUSTEREDऔर ऐसा पहले से मौजूद न हो;

2

इसे प्राथमिक कुंजी बनाते हुए स्वचालित रूप से इसके लिए एक सूचकांक भी बनाना चाहिए।


1

खैर SQL सर्वर में, आम तौर पर, प्राथमिक कुंजी स्वचालित रूप से अनुक्रमित होती है। यह सच है, लेकिन यह तेज क्वेरी की गारंटी नहीं देता है। प्राथमिक कुंजी आपको उत्कृष्ट प्रदर्शन देगी जब प्राथमिक कुंजी के रूप में केवल 1 फ़ील्ड है। लेकिन, जब प्राथमिक कुंजी के रूप में कई क्षेत्र होते हैं, तो सूचकांक उन क्षेत्रों पर आधारित होता है।

उदाहरण के लिए: फ़ील्ड A, B, C प्राथमिक कुंजी हैं, इस प्रकार जब आप अपने WHERE CLAUSE में उन 3 फ़ील्डों के आधार पर क्वेरी करते हैं, तो प्रदर्शन अच्छा है, लेकिन जब आप WHA CLAUSE में केवल C फ़ील्ड के साथ क्वेरी करना चाहते हैं, तो आप अच्छा प्रदर्शन नहीं मिलेगा। इस प्रकार, अपने प्रदर्शन को बढ़ाने और चलाने के लिए, आपको सी फ़ील्ड को मैन्युअल रूप से अनुक्रमित करना होगा।

जब तक आप 1 मिलियन से अधिक रिकॉर्ड को हिट नहीं करते, तब तक अधिकांश समय आप इस मुद्दे को नहीं देखेंगे।


0

मेरे पास बिना (अलग) इंडेक्स वाला एक विशाल डेटाबेस है।

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


ऐसा इसलिए है क्योंकि PK एक संकुल सूचकांक है, अपनी क्वेरी योजना
SQLMenace को देखें

0

प्राथमिक कुंजियाँ स्वचालित रूप से अनुक्रमित की जाती हैं

आप अपने उपयोग के आधार पर pk का उपयोग करके अतिरिक्त सूचकांक बना सकते हैं

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