बहुत अच्छा सवाल है क्योंकि यह इतनी महत्वपूर्ण अवधारणा है। हालांकि यह एक बड़ा विषय है और जो मैं आपको दिखाने जा रहा हूं वह एक सरलीकरण है ताकि आप आधार अवधारणाओं को समझ सकें।
सबसे पहले जब आप क्लस्टर इंडेक्स थिंक टेबल देखते हैं । SQL सर्वर में यदि किसी टेबल में क्लस्टर इंडेक्स नहीं होता है तो वह ढेर होता है। तालिका पर एक क्लस्टर इंडेक्स बनाना वास्तव में तालिका को बी-ट्री प्रकार की संरचना में बदल देता है। आपका संकुल सूचकांक आपकी तालिका है यह तालिका से अलग नहीं है
कभी आपने सोचा है कि आपके पास केवल एक क्लस्टर इंडेक्स क्यों हो सकता है? यदि हमारे पास दो क्लस्टर इंडेक्स हैं तो हमें टेबल की दो प्रतियों की आवश्यकता होगी। इसमें आखिर डेटा होता है।
मैं एक सरल उदाहरण का उपयोग करके इसे समझाने और समझाने जा रहा हूं।
नोट: मैंने इस उदाहरण में तालिका बनाई और इसे 3 मिलियन से अधिक यादृच्छिक प्रविष्टियों से भर दिया। फिर वास्तविक प्रश्नों को चलाया और निष्पादन योजनाओं को यहाँ चिपकाया।
क्या आप वास्तव में समझ की जरूरत है ओ संकेतन या परिचालन क्षमता है । मान लेते हैं कि आपके पास निम्न तालिका है।
CREATE TABLE [dbo].[Customer](
[CustomerID] [int] IDENTITY(1,1) NOT NULL,
[CustomerName] [varchar](100) NOT NULL,
[CustomerSurname] [varchar](100) NOT NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED
(
[CustomerID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF
, IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
इसलिए यहां हमारे पास CustomerID पर एक संकुल कुंजी के साथ मूल तालिका है (प्राथमिक कुंजी डिफ़ॉल्ट रूप से क्लस्टर की गई है)। इस प्रकार प्राथमिक मुख्य ग्राहक के आधार पर तालिका की व्यवस्था / आदेश दिया जाता है। मध्यवर्ती स्तरों में CustomerID मान शामिल होंगे। डेटा पृष्ठों में पूरी पंक्ति होगी, इस प्रकार यह तालिका पंक्ति है।
हम CustomerName फ़ील्ड पर एक गैर-क्लस्टर इंडेक्स भी बनाएंगे। निम्न कोड यह करेगा।
CREATE NONCLUSTERED INDEX [ix_Customer_CustomerName] ON [dbo].[Customer]
(
[CustomerName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF
, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF
, DROP_EXISTING = OFF, ONLINE = OFF
, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
तो इस इंडेक्स में आपको डेटा पेज / लीफ लेवल नोड्स पर एक सूचक को क्लस्टर किए गए इंडेक्स में इंटरमीडिएट लेवल पर बताता है। ग्राहक नाम फ़ील्ड के चारों ओर सूचकांक को व्यवस्थित / आदेशित किया जाता है। इस प्रकार मध्यवर्ती स्तर में CustomerName मान शामिल हैं और पत्ती स्तर में पॉइंटर होगा (ये पॉइंटर मान वास्तव में प्राथमिक कुंजी मान या CustomerID स्तंभ हैं)।
ठीक है अगर हम निम्नलिखित प्रश्न को निष्पादित करते हैं:
SELECT * FROM Customer WHERE CustomerID = 1
एसक्यूएल शायद एक तलाश ऑपरेशन के माध्यम से क्लस्टर इंडेक्स को पढ़ेगा। एक तलाश ऑपरेशन एक द्विआधारी खोज है जो स्कैन की तुलना में बहुत अधिक कुशल है जो अनुक्रमिक खोज है। इसलिए हमारे उपरोक्त उदाहरण में सूचकांक को पढ़ा जाता है और एक बाइनरी सर्च एसक्यूएल का उपयोग करके डेटा को समाप्त किया जा सकता है जो उन मानदंडों से मेल नहीं खाता है जो हम खोज रहे हैं। क्वेरी योजना के लिए संलग्न स्क्रीन शॉट देखें।
इसलिए ऑपरेशन के लिए ऑपरेशन या ओ नोटेशन की संख्या इस प्रकार है:
- मध्यवर्ती स्तर के मानों के लिए खोजे गए मूल्य की तुलना करके संकुल सूचकांक पर द्विआधारी खोज करें।
- जो मान मेल खाते हैं उन्हें लौटाएं (याद रखें कि चूंकि क्लस्टर इंडेक्स में सभी डेटा हैं, इसलिए इंडेक्स से सभी कॉलम वापस कर सकते हैं क्योंकि यह पंक्ति डेटा है)
तो यह दो ऑपरेशन है। हालाँकि अगर हमने निम्नलिखित क्वेरी को निष्पादित किया है:
SELECT * FROM Customer WHERE CustomerName ='John'
एसक्यूएल अब सर्च करने के लिए कस्टमरनाम पर नॉन-क्लस्टर्ड इंडेक्स का उपयोग करेगा। हालाँकि, यह एक गैर-संकुल सूचकांक है क्योंकि इसमें पंक्ति के सभी डेटा शामिल नहीं हैं।
इसलिए SQL उस मिलान को खोजने के लिए मध्यवर्ती स्तरों पर खोज करेगा और वास्तविक डेटा को पुनः प्राप्त करने के लिए संकुल इंडेक्स (उर्फ टेबल) पर एक और खोज करने के लिए दिए गए मानों का उपयोग करके एक लुकअप करेगा। यह भ्रमपूर्ण लगता है कि मैं जानता हूं, लेकिन पढ़ता हूं और सब स्पष्ट हो जाएगा।
चूंकि हमारे गैर-संकुलित सूचकांक में केवल ग्राहक नाम फ़ील्ड (मध्यवर्ती नोड्स में संग्रहीत अनुक्रमित फ़ील्ड मान) और डेटा जो ग्राहक है, का सूचक होता है, सूचकांक में ग्राहक नाम का कोई रिकॉर्ड नहीं होता है। CustomerSurname को क्लस्टर इंडेक्स या टेबल से प्राप्त करना होगा।
इस क्वेरी को चलाते समय मुझे निम्नलिखित निष्पादन योजना मिलती है:
ऊपर दिए गए स्क्रीन शॉट में आपके लिए दो महत्वपूर्ण बातें हैं
- SQL कह रहा है कि मेरे पास एक लापता सूचकांक (हरे रंग में पाठ) है। SQL सुझाव दे रहा है कि मैं CustomerName पर एक इंडेक्स बनाऊं जिसमें CustomerID और CustomerSurname शामिल हों।
- आप यह भी देखेंगे कि क्वेरी का 99% समय प्राथमिक कुंजी इंडेक्स / क्लस्टर इंडेक्स पर एक प्रमुख लुकअप करने में खर्च होता है।
SQL फिर CustomerName पर सूचकांक का सुझाव क्यों दे रहा है? खैर चूंकि इंडेक्स में केवल CustomerID और CustomerName SQL होता है, फिर भी टेबल / क्लस्टर इंडेक्स से CustomerSurname खोजना पड़ता है।
यदि हमने इंडेक्स बनाया है और हमने कस्टमरसर्नाम कॉलम को इंडेक्स में शामिल किया है तो केवल गैर-क्लस्टर इंडेक्स को पढ़कर पूरी क्वेरी को संतुष्ट करने में सक्षम होगा। यही कारण है कि एसक्यूएल सुझाव दे रहा है कि मैं अपने गैर-संकुल सूचकांक को बदल दूं।
यहाँ आप देख सकते हैं कि एक्स्ट्रा ऑपरेशन SQL को क्लस्टर किए गए कुंजी से CustomerSurname कॉलम प्राप्त करने की आवश्यकता है
इस प्रकार संचालन की संख्या इस प्रकार है:
- मध्यवर्ती स्तर के मूल्यों के लिए खोजे गए मूल्य की तुलना करके गैर-संकुल सूचकांक पर द्विआधारी खोज करें
- नोड्स के लिए जो मैच लीफ लेवल नोड को पढ़ता है जिसमें क्लस्टर इंडेक्स में डेटा के लिए पॉइंटर होगा (लीफ लेवल नोड्स में प्राथमिक कुंजी मान शामिल होंगे)।
- लौटाए गए मूल्य (तालिका) को पंक्ति मान पर पढ़ने के लिए लौटाए गए प्रत्येक मान के लिए, यहां हम ग्राहक उपनाम पढ़ेंगे।
- मिलान पंक्तियों को वापस करें
मानों को बाहर निकालने के लिए यह 4 ऑपरेशन हैं। दो बार क्लस्टर किए गए इंडेक्स को पढ़ने की तुलना में आवश्यक संचालन की मात्रा। शो आपको बताता है कि आपका क्लस्टर इंडेक्स आपका सबसे शक्तिशाली इंडेक्स है क्योंकि इसमें सभी डेटा होते हैं।
तो बस एक अंतिम बिंदु को स्पष्ट करने के लिए। मैं क्यों कहता हूं कि गैर-संकुल सूचकांक में सूचक प्राथमिक कुंजी मूल्य है? यह प्रदर्शित करने के लिए कि गैर-संकुल सूचकांक के पत्ती स्तर के नोड्स में प्राथमिक कुंजी मान होता है जिसे मैं अपनी क्वेरी में बदलता हूं:
SELECT CustomerID
FROM Customer
WHERE CustomerName='Jane'
इस क्वेरी में SQL गैर-संकुल अनुक्रमणिका से CustomerID को पढ़ सकता है। इसे क्लस्टर इंडेक्स पर लुकअप करने की जरूरत नहीं है। यह आप निष्पादन योजना द्वारा देख सकते हैं जो इस तरह दिखता है।
इस क्वेरी और पिछले क्वेरी के बीच अंतर पर ध्यान दें। कोई खोज नहीं है। SQL सभी डेटा को गैर-संकुलित सूचकांक में पा सकता है
उम्मीद है कि आप यह समझना शुरू कर सकते हैं कि क्लस्टर इंडेक्स टेबल है और गैर-क्लस्टर इंडेक्स DON'T में सभी डेटा नहीं हैं। अनुक्रमण इस तथ्य के कारण चयन को गति देगा कि बाइनरी खोज की जा सकती है, लेकिन केवल संकुल अनुक्रमणिका में सभी डेटा होते हैं। अतः गुच्छित सूचकांक पर एक खोज लगभग हमेशा संकुल सूचकांक से लोड किए जा रहे मूल्यों के परिणामस्वरूप होगी। ये अतिरिक्त ऑपरेशन गैर-संकुलित अनुक्रमणिका को क्लस्टर किए गए अनुक्रमणिका से कम कुशल बनाते हैं।
आशा है, इससे स्थिति स्पष्ट हो जाएगी। अगर कुछ भी मतलब नहीं है तो कृपया एक टिप्पणी पोस्ट करें और मैं स्पष्ट करने की कोशिश करूंगा। यह यहाँ देर हो चुकी है और मेरा दिमाग एक अजीब सा फ्लैट महसूस कर रहा है। लाल बैल का समय।