आशावादी गैर-क्लस्टर सूचकांक के बजाय क्लस्टर इंडेक्स + सॉर्ट क्यों चुनेंगे?


11

अगले उदाहरण को देखते हुए:

IF OBJECT_ID('dbo.my_table') IS NOT NULL
    DROP TABLE [dbo].[my_table];
GO

CREATE TABLE [dbo].[my_table]
(
    [id]    int IDENTITY (1,1)  NOT NULL PRIMARY KEY,
    [foo]   int                 NULL,
    [bar]   int                 NULL,
    [nki]   int                 NOT NULL
);
GO

/* Insert some random data */
INSERT INTO [dbo].[my_table] (foo, bar, nki)
SELECT TOP (100000)
    ABS(CHECKSUM(NewId())) % 14,
    ABS(CHECKSUM(NewId())) % 20,
    n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
FROM 
    sys.all_objects AS s1 
CROSS JOIN 
    sys.all_objects AS s2
GO

CREATE UNIQUE NONCLUSTERED INDEX [IX_my_table]
    ON [dbo].[my_table] ([nki] ASC);
GO

यदि मैं [nki](गैर-संकुल सूचकांक) द्वारा आदेशित सभी रिकॉर्ड प्राप्त करता हूं :

SET STATISTICS TIME ON;
SELECT id, foo, bar, nki FROM my_table ORDER BY nki;
SET STATISTICS TIME OFF;

SQL Server Execution Times: CPU time = 266 ms, elapsed time = 493 ms

ऑप्टिमाइज़र क्लस्टर किए गए इंडेक्स को चुनता है और फिर एक सॉर्ट एल्गोरिथ्म लागू करता है।

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

Execution plan

लेकिन अगर मैं इसे गैर-संकुल सूचकांक का उपयोग करने के लिए मजबूर करता हूं:

SET STATISTICS TIME ON;
SELECT id, foo, bar, nki FROM my_table WITH(INDEX(IX_my_TABLE));
SET STATISTICS TIME OFF;

SQL Server Execution Times: CPU time = 311 ms, elapsed time = 188 ms

तब यह एक कुंजी लुकअप के साथ गैर-संकुल सूचकांक का उपयोग करता है:

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

Execution plan

स्पष्ट रूप से अगर गैर-संकुलित सूचकांक एक आवरण सूचकांक में बदल जाता है:

CREATE UNIQUE NONCLUSTERED INDEX [IX_my_table]
    ON [dbo].[my_table] ([nki] ASC)
    INCLUDE (id, foo, bar);
GO

तब यह केवल इस सूचकांक का उपयोग करता है:

SET STATISTICS TIME ON;
SELECT id, foo, bar, nki FROM my_table ORDER BY nki;
SET STATISTICS TIME OFF;

SQL Server Execution Times: CPU time = 32 ms, elapsed time = 106 ms

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

Execution plan


सवाल

  • SQL सर्वर क्‍लस्‍युर्ड इंडेक्स प्‍लस का उपयोग क्‍यों करता है और नॉन-क्‍लस्‍टर इंडेक्स का उपयोग करने के बजाय एक सॉर्ट अल्गोरिदम का उपयोग करता है, भले ही बाद के मामले में निष्पादन का समय 38% तेज हो?

1
क्या आपने अपनी मजबूर-सूचकांक क्वेरी में ORDER BY को छोड़ने का मतलब है?
फॉरेस्ट

जवाबों:


9

SQL सर्वर क्‍लस्‍युर्ड इंडेक्स प्‍लस का उपयोग क्‍यों करता है और नॉन-क्‍लस्‍टर इंडेक्स का उपयोग करने के बजाय एक सॉर्ट अल्गोरिदम का उपयोग करता है, भले ही बाद के मामले में निष्पादन का समय 38% तेज हो?

क्योंकि SQL सर्वर आँकड़ों के आधार पर लागत-आधारित ऑप्टिमाइज़र का उपयोग करता है, न कि रनटाइम जानकारी के लिए।

इस क्वेरी के लिए लागत अनुमान प्रक्रिया के दौरान, यह वास्तव में लुकअप प्लान का मूल्यांकन करता है, लेकिन अनुमान है कि यह अधिक प्रयास करेगा। (निष्पादन योजना में चयन पर मँडरा करते समय "अनुमानित सबट्री कॉस्ट" पर ध्यान दें)। यह जरूरी नहीं कि एक बुरी धारणा है - मेरी परीक्षण मशीन पर, लुकअप योजना 6X सीपीयू को सॉर्ट / स्कैन करती है।

रॉब फ़र्ले के जवाब के रूप में देखें कि SQL सर्वर लुकअप प्लान को अधिक खर्च कर सकता है।


9

यदि आप 1,00,000 लुकअप में आवश्यक रीड्स की संख्या की तुलना करना चाहते हैं, जो कि किस प्रकार को करने में शामिल है, तो आप जल्दी से इस बारे में एक विचार प्राप्त कर सकते हैं कि क्वेरी ऑप्टिमाइज़र ने यह क्यों देखा कि CIX + Sort सबसे अच्छा विकल्प होगा।

लुकअप निष्पादन तेज़ी से समाप्त हो रहा है क्योंकि पढ़े जा रहे पृष्ठ स्मृति में हैं (भले ही आप कैश साफ़ करें, आपके पास प्रति पृष्ठ बहुत पंक्तियाँ हैं, इसलिए आप एक ही पृष्ठ को बार-बार पढ़ रहे हैं, लेकिन विखंडन की विभिन्न मात्राओं के साथ या अन्य गतिविधि से अलग स्मृति दबाव, यह मामला नहीं हो सकता है)। यह वास्तव में CIX + सॉर्ट करने के लिए इतना सब नहीं ले जाएगा, लेकिन आप जो देख रहे हैं, वह यह है कि एक रीड की लागत बार-बार एक ही पेज को हिट करने के सापेक्ष सस्तेपन को ध्यान में नहीं रखती है।


4

मैंने इस सवाल पर थोड़ा खुदाई करने का फैसला किया है और मुझे कुछ दिलचस्प दस्तावेजों के बारे में पता चला है कि कैसे और कब उपयोग किया जाता है या बेहतर हो सकता है, गैर-संकुल सूचकांक के उपयोग (बल) का उपयोग नहीं करना चाहिए।

जैसा कि जॉन Eisbrener की टिप्पणियों के अनुसार , सबसे संदर्भित में से एक है, यहां तक ​​कि दूसरों के ब्लॉग में भी, किम्बरली एल। ट्रिप्प का यह दिलचस्प लेख है:

लेकिन यह केवल एक ही नहीं है, यदि आप रुचि रखते हैं तो आप इस पृष्ठ पर एक नज़र डाल सकते हैं:

जैसा कि आप देख सकते हैं, ये सभी टिपिंग बिंदु की अवधारणा के चारों ओर घूमते हैं ।

केएल ट्रिप लेख से उद्धृत

टिपिंग बिंदु क्या है?

यह वह बिंदु है जहाँ पंक्तियों की संख्या " अब पर्याप्त चयनात्मक नहीं " है। SQL सर्वर गैर-संकुल अनुक्रमणिका का उपयोग करने के लिए संबंधित डेटा पंक्तियों को देखने के लिए नहीं चुनता है और इसके बजाय एक तालिका स्कैन करता है।

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

लेकिन, जब वह टिपिंग बिंदु होता है?

बेशक इस जीवन में ज्यादातर चीजें हैं, यह निर्भर करता है ...

गंभीरता से नहीं, यह प्रति पृष्ठ कितनी पंक्तियों के आधार पर तालिका में पृष्ठों की संख्या के 25% से 33% के बीच होता है। लेकिन ऐसे और भी कारक हैं जिन पर आपको विचार करना चाहिए:

ITPRoToday लेख से उद्धृत

टिपिंग प्वाइंट को प्रभावित करने वाले अन्य कारक हालांकि RID लुकअप की लागत सबसे महत्वपूर्ण कारक है जो टिपिंग बिंदु को प्रभावित करता है, कई अन्य कारक हैं:

  • फिजिकल इंडेक्स को स्कैन करते समय फिजिकल I / O ज्यादा कुशल होता है। अनुक्रमणिका क्रम में डिस्क पर क्रस्टर्ड इंडेक्स डेटा को क्रमिक रूप से रखा गया है। नतीजतन, डिस्क पर बहुत कम पार्श्व सिर की यात्रा होती है, जो I / O प्रदर्शन में सुधार करती है।
  • जब डेटाबेस इंजन एक क्लस्टर इंडेक्स को स्कैन कर रहा होता है, तो यह जानता है कि एक उच्च संभावना है कि डिस्क ट्रैक पर अगले कुछ पेज अभी भी डेटा की आवश्यकता होगी। तो, यह सामान्य 8KB पृष्ठों के बजाय 64KB विखंडू में आगे पढ़ना शुरू करता है। यह भी तेजी से मैं / हे में परिणाम है।

अब अगर मैं सांख्यिकी IO का उपयोग करके अपने प्रश्नों को फिर से निष्पादित करता हूं:

SET STATISTICS IO ON;
SELECT id, foo, bar, nki FROM my_table WHERE nki < 20000 ORDER BY nki ;
SET STATISTICS IO OFF;

Logical reads: 312

SET STATISTICS IO ON;
SELECT id, foo, bar, nki FROM my_table WITH(INDEX(IX_my_TABLE));
SET STATISTICS IO OFF;

Logical reads: 41293

दूसरी क्वेरी को पहले वाले की तुलना में अधिक तार्किक रीड की आवश्यकता है।

क्या मुझे गैर-संकुलित सूचकांक से बचना चाहिए?

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

केएल ट्रिप लेख से उद्धृत

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

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

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