क्लस्टर्ड और नॉन क्लस्टर्ड इंडेक्स के बीच प्रदर्शन अंतर


22

मैं पढ़ रहा था Clusteredऔर Non Clustered Indexes

Clustered Index- इसमें डेटा पेज होते हैं। इसका मतलब है कि पूरी पंक्ति की जानकारी क्लस्टर इंडेक्स कॉलम में मौजूद होगी।

Non Clustered Index- इसमें केवल Clustered Index column (if availabe) या File Indentifier + Page Number + Total Rows in a Page के रूप में Row Locator की जानकारी होती है। इसका मतलब है कि वास्तविक डेटा का पता लगाने के लिए क्वेरी इंजन को एक अतिरिक्त कदम उठाना होगा।

क्वेरी - मैं कैसे एक व्यावहारिक उदाहरण के एक मदद से प्रदर्शन अंतर जाँच कर सकते हैं के रूप में हम जानते हैं कि तालिका में केवल एक ही है कि कर सकते हैं Clustered Indexऔर प्रदान करता है sortingपर Clustered Index Columnऔर Non Clustered Indexप्रदान नहीं करते हैं sortingऔर 999 का समर्थन कर सकते Non Clustered Indexesमें SQL Server 2008में और 249 SQL Server 2005


2
जब आप क्या करते हैं तो प्रदर्शन में अंतर होता है ?, आप उस टेबल के साथ किस तरह का काम करना चाहते हैं ?, एक भी ऐसा उपाय नहीं है जो हर जरूरत के
अनुकूल हो

2
शायद यहाँ कुछ मूर्त चर्चा। stackoverflow.com/questions/91688/… stackoverflow.com/questions/5070529/… stackoverflow.com/questions/1251636/… हम क्लस्टर और गैर-क्लस्टर इंडेक्स के बीच अंतर के बारे में एक शोध प्रबंध लिख सकते हैं, लेकिन मुझे नहीं लगता कि हम ऐसा कुछ भी कहेंगे जो आपको पढ़ने के लिए पहले से उपलब्ध न हो।
एरॉन बर्ट्रेंड

4
आपने लिखा है: "इसका मतलब है कि वास्तविक डेटा का पता लगाने के लिए क्वेरी इंजन को एक अतिरिक्त कदम उठाना होगा।" वास्तव में, यदि आपको सूचकांक में शामिल किए जाने वाले सभी कॉलम हैं , तो आपको गैर- अनुक्रमित सूचकांक में अपनी लक्ष्य पंक्तियों को खोजने के बाद कोई अतिरिक्त कदम उठाने की आवश्यकता नहीं है। जब आपको नॉनक्लेस्टेड इंडेक्स द्वारा कवर नहीं किए जाने वाले कॉलमों की आवश्यकता होती है, केवल SQL सर्वर को बुकमार्क लुकअप करने की आवश्यकता होती है ।
निक चामास

जवाबों:


43

बहुत अच्छा सवाल है क्योंकि यह इतनी महत्वपूर्ण अवधारणा है। हालांकि यह एक बड़ा विषय है और जो मैं आपको दिखाने जा रहा हूं वह एक सरलीकरण है ताकि आप आधार अवधारणाओं को समझ सकें।

सबसे पहले जब आप क्लस्टर इंडेक्स थिंक टेबल देखते हैं । 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 

एसक्यूएल शायद एक तलाश ऑपरेशन के माध्यम से क्लस्टर इंडेक्स को पढ़ेगा। एक तलाश ऑपरेशन एक द्विआधारी खोज है जो स्कैन की तुलना में बहुत अधिक कुशल है जो अनुक्रमिक खोज है। इसलिए हमारे उपरोक्त उदाहरण में सूचकांक को पढ़ा जाता है और एक बाइनरी सर्च एसक्यूएल का उपयोग करके डेटा को समाप्त किया जा सकता है जो उन मानदंडों से मेल नहीं खाता है जो हम खोज रहे हैं। क्वेरी योजना के लिए संलग्न स्क्रीन शॉट देखें।

यहाँ छवि विवरण दर्ज करें

इसलिए ऑपरेशन के लिए ऑपरेशन या ओ नोटेशन की संख्या इस प्रकार है:

  1. मध्यवर्ती स्तर के मानों के लिए खोजे गए मूल्य की तुलना करके संकुल सूचकांक पर द्विआधारी खोज करें।
  2. जो मान मेल खाते हैं उन्हें लौटाएं (याद रखें कि चूंकि क्लस्टर इंडेक्स में सभी डेटा हैं, इसलिए इंडेक्स से सभी कॉलम वापस कर सकते हैं क्योंकि यह पंक्ति डेटा है)

तो यह दो ऑपरेशन है। हालाँकि अगर हमने निम्नलिखित क्वेरी को निष्पादित किया है:

SELECT * FROM Customer WHERE CustomerName ='John'

एसक्यूएल अब सर्च करने के लिए कस्टमरनाम पर नॉन-क्लस्टर्ड इंडेक्स का उपयोग करेगा। हालाँकि, यह एक गैर-संकुल सूचकांक है क्योंकि इसमें पंक्ति के सभी डेटा शामिल नहीं हैं।

इसलिए SQL उस मिलान को खोजने के लिए मध्यवर्ती स्तरों पर खोज करेगा और वास्तविक डेटा को पुनः प्राप्त करने के लिए संकुल इंडेक्स (उर्फ टेबल) पर एक और खोज करने के लिए दिए गए मानों का उपयोग करके एक लुकअप करेगा। यह भ्रमपूर्ण लगता है कि मैं जानता हूं, लेकिन पढ़ता हूं और सब स्पष्ट हो जाएगा।

चूंकि हमारे गैर-संकुलित सूचकांक में केवल ग्राहक नाम फ़ील्ड (मध्यवर्ती नोड्स में संग्रहीत अनुक्रमित फ़ील्ड मान) और डेटा जो ग्राहक है, का सूचक होता है, सूचकांक में ग्राहक नाम का कोई रिकॉर्ड नहीं होता है। CustomerSurname को क्लस्टर इंडेक्स या टेबल से प्राप्त करना होगा।

इस क्वेरी को चलाते समय मुझे निम्नलिखित निष्पादन योजना मिलती है:

यहाँ छवि विवरण दर्ज करें

ऊपर दिए गए स्क्रीन शॉट में आपके लिए दो महत्वपूर्ण बातें हैं

  1. SQL कह रहा है कि मेरे पास एक लापता सूचकांक (हरे रंग में पाठ) है। SQL सुझाव दे रहा है कि मैं CustomerName पर एक इंडेक्स बनाऊं जिसमें CustomerID और CustomerSurname शामिल हों।
  2. आप यह भी देखेंगे कि क्वेरी का 99% समय प्राथमिक कुंजी इंडेक्स / क्लस्टर इंडेक्स पर एक प्रमुख लुकअप करने में खर्च होता है।

SQL फिर CustomerName पर सूचकांक का सुझाव क्यों दे रहा है? खैर चूंकि इंडेक्स में केवल CustomerID और CustomerName SQL होता है, फिर भी टेबल / क्लस्टर इंडेक्स से CustomerSurname खोजना पड़ता है।

यदि हमने इंडेक्स बनाया है और हमने कस्टमरसर्नाम कॉलम को इंडेक्स में शामिल किया है तो केवल गैर-क्लस्टर इंडेक्स को पढ़कर पूरी क्वेरी को संतुष्ट करने में सक्षम होगा। यही कारण है कि एसक्यूएल सुझाव दे रहा है कि मैं अपने गैर-संकुल सूचकांक को बदल दूं।

यहाँ आप देख सकते हैं कि एक्स्ट्रा ऑपरेशन SQL को क्लस्टर किए गए कुंजी से CustomerSurname कॉलम प्राप्त करने की आवश्यकता है

इस प्रकार संचालन की संख्या इस प्रकार है:

  1. मध्यवर्ती स्तर के मूल्यों के लिए खोजे गए मूल्य की तुलना करके गैर-संकुल सूचकांक पर द्विआधारी खोज करें
  2. नोड्स के लिए जो मैच लीफ लेवल नोड को पढ़ता है जिसमें क्लस्टर इंडेक्स में डेटा के लिए पॉइंटर होगा (लीफ लेवल नोड्स में प्राथमिक कुंजी मान शामिल होंगे)।
  3. लौटाए गए मूल्य (तालिका) को पंक्ति मान पर पढ़ने के लिए लौटाए गए प्रत्येक मान के लिए, यहां हम ग्राहक उपनाम पढ़ेंगे।
  4. मिलान पंक्तियों को वापस करें

मानों को बाहर निकालने के लिए यह 4 ऑपरेशन हैं। दो बार क्लस्टर किए गए इंडेक्स को पढ़ने की तुलना में आवश्यक संचालन की मात्रा। शो आपको बताता है कि आपका क्लस्टर इंडेक्स आपका सबसे शक्तिशाली इंडेक्स है क्योंकि इसमें सभी डेटा होते हैं।

तो बस एक अंतिम बिंदु को स्पष्ट करने के लिए। मैं क्यों कहता हूं कि गैर-संकुल सूचकांक में सूचक प्राथमिक कुंजी मूल्य है? यह प्रदर्शित करने के लिए कि गैर-संकुल सूचकांक के पत्ती स्तर के नोड्स में प्राथमिक कुंजी मान होता है जिसे मैं अपनी क्वेरी में बदलता हूं:

SELECT CustomerID
FROM Customer
WHERE CustomerName='Jane'

इस क्वेरी में SQL गैर-संकुल अनुक्रमणिका से CustomerID को पढ़ सकता है। इसे क्लस्टर इंडेक्स पर लुकअप करने की जरूरत नहीं है। यह आप निष्पादन योजना द्वारा देख सकते हैं जो इस तरह दिखता है।

यहाँ छवि विवरण दर्ज करें

इस क्वेरी और पिछले क्वेरी के बीच अंतर पर ध्यान दें। कोई खोज नहीं है। SQL सभी डेटा को गैर-संकुलित सूचकांक में पा सकता है

उम्मीद है कि आप यह समझना शुरू कर सकते हैं कि क्लस्टर इंडेक्स टेबल है और गैर-क्लस्टर इंडेक्स DON'T में सभी डेटा नहीं हैं। अनुक्रमण इस तथ्य के कारण चयन को गति देगा कि बाइनरी खोज की जा सकती है, लेकिन केवल संकुल अनुक्रमणिका में सभी डेटा होते हैं। अतः गुच्छित सूचकांक पर एक खोज लगभग हमेशा संकुल सूचकांक से लोड किए जा रहे मूल्यों के परिणामस्वरूप होगी। ये अतिरिक्त ऑपरेशन गैर-संकुलित अनुक्रमणिका को क्लस्टर किए गए अनुक्रमणिका से कम कुशल बनाते हैं।

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


मेरा एक सवाल है। WHY एक खोज है जो इस क्वेरी के लिए ग्राहक नाम पर गैर-संकुल सूचकांक पर एक सूचकांक की तलाश करता है * ग्राहक से ग्राहक का चयन करें जहां ग्राहक नाम = 'जॉन' है। चूँकि यह एक नॉन क्लस्टर्ड इंडेक्स है इसलिए कस्टमनेम को छाँटा नहीं जाएगा। इसलिए इंडेक्स स्कैन नहीं करना चाहिए।
ckv

BTW महान जवाब उपरोक्त प्रश्न को छोड़कर पूरी तरह से समझा।
सीकेवी 24'13

1
डेटा के क्रम में एक इंडेक्स को क्रमबद्ध किया जाता है। उदाहरण के लिए इसे अनुक्रमित मान के बाद से ग्राहक के नाम पर क्रमबद्ध किया जाएगा। इसलिए इसे क्रमबद्ध किया जाता है। याद रखें कि यह अभी भी पत्ती स्तर या पृष्ठों को स्कैन करना है।
नामीबियाई

9

"इसका मतलब है कि वास्तविक डेटा का पता लगाने के लिए क्वेरी इंजन को एक अतिरिक्त कदम उठाना होगा।"

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

तो अंतिम उत्तर है - यह निर्भर करता है (एक बहुत अधिक जानकारी की तुलना में आप वास्तव में एक ही प्रश्न में कवर कर सकते हैं) - आपको सूचकांक की सभी क्षमताओं को समझने की आवश्यकता है और किसी दिए गए प्रश्न के लिए निष्पादन योजना आपकी उम्मीदों से अलग हो सकती है।

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

और मुझे अनुमति नहीं है कि विभिन्न अनुक्रमित पर सीमा के बारे में चिंता न करें - यह लगभग निश्चित रूप से कई वास्तविक दुनिया के उदाहरणों में खेलने के लिए नहीं है।


2
+1 के लिए there are always exceptions- बहुत से लोग इसे छोड़ देते हैं और सोचते हैं कि प्रत्येक संकुल सूचकांक को int identityकोई फर्क नहीं पड़ता कि क्या होना चाहिए ।
जेएनके
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.