SQL सर्वर अनुक्रमित - आरोही या अवरोही, इससे क्या फर्क पड़ता है?


138

जब आप MS SQL Server (मैं संस्करण 2005 का उपयोग कर रहा हूं) के एक कॉलम या कॉलम पर एक इंडेक्स बनाते हैं, तो आप निर्दिष्ट कर सकते हैं कि प्रत्येक कॉलम पर इंडेक्स या तो आरोही या अवरोही हो। मुझे यह समझने में कठिन समय हो रहा है कि यह विकल्प यहां भी क्यों है। बाइनरी सॉर्ट तकनीक का उपयोग करते हुए, क्या लुकअप या तो तेज नहीं होगा? इससे क्या फर्क पड़ता है कि मैं कौन सा आदेश चुनूं?


जवाबों:


136

कंपोजिट इंडेक्स के साथ उपयोग किए जाने पर यह मुख्य रूप से मायने रखता है:

CREATE INDEX ix_index ON mytable (col1, col2 DESC);

या तो के लिए इस्तेमाल किया जा सकता है:

SELECT  *
FROM    mytable
ORDER BY
        col1, col2 DESC

या:

SELECT  *
FROM    mytable
ORDER BY
        col1 DESC, col2

, लेकिन इसके लिए नहीं:

SELECT  *
FROM    mytable
ORDER BY
        col1, col2

एकल कॉलम पर एक इंडेक्स को दोनों तरह से छांटने के लिए कुशलतापूर्वक उपयोग किया जा सकता है।

विवरण के लिए मेरे ब्लॉग में लेख देखें:

अपडेट करें:

वास्तव में, यह एकल कॉलम इंडेक्स के लिए भी मायने रख सकता है, हालांकि यह इतना स्पष्ट नहीं है।

एक तालिका की एक स्तंभ पर एक सूचकांक की कल्पना करो:

CREATE TABLE mytable (
       pk INT NOT NULL PRIMARY KEY,
       col1 INT NOT NULL
)
CREATE INDEX ix_mytable_col1 ON mytable (col1)

अनुक्रमित पंक्तियों के संदर्भ के साथ-साथ col1क्रमबद्ध मूल्यों को रखता है col1

चूँकि तालिका को क्लस्ट किया गया है, पंक्तियों के संदर्भ वास्तव में हैं pk। वे भी प्रत्येक मूल्य के भीतर दिए गए हैं col1

इसका मतलब यह है कि सूचकांक के पत्ते वास्तव में आदेश दिए गए हैं (col1, pk), और यह प्रश्न:

SELECT  col1, pk
FROM    mytable
ORDER BY
        col1, pk

कोई छँटाई की जरूरत है।

यदि हम निम्नलिखित के रूप में सूचकांक बनाते हैं:

CREATE INDEX ix_mytable_col1_desc ON mytable (col1 DESC)

, तब के मूल्यों को col1अवरोही क्रमबद्ध किया जाएगा, लेकिन pkप्रत्येक मूल्य के भीतर के मूल्यों को col1आरोही क्रमबद्ध किया जाएगा।

इसका मतलब है कि निम्नलिखित प्रश्न:

SELECT  col1, pk
FROM    mytable
ORDER BY
        col1, pk DESC

द्वारा सेवा की जा सकती है ix_mytable_col1_descलेकिन द्वारा नहीं ix_mytable_col1

दूसरे शब्दों में, CLUSTERED INDEXकिसी भी तालिका पर बनने वाले स्तंभ हमेशा उस तालिका के किसी अन्य सूचकांक के अनुगामी स्तंभ होते हैं।


1
जब आप कहते हैं कि "नहीं ..." का मतलब है कि यह काम नहीं करेगा या प्रदर्शन भयानक होगा?
नील एन

5
मेरा मतलब है कि इंडेक्स क्वेरी के लिए उपयोग नहीं किया जाएगा। क्वेरी स्वयं काम करेगी, निश्चित रूप से, लेकिन प्रदर्शन खराब होगा।
क्वासोई

1
पहले खंड में, दूसरा उदाहरण "ORDER BY col1 DESC, col2 DESC" नहीं कहना चाहिए?
मिच गेहूं

71

एक सच्चे एकल कॉलम इंडेक्स के लिए यह क्वेरी ऑप्टिमाइज़र के दृष्टिकोण से बहुत कम अंतर रखता है।

तालिका परिभाषा के लिए

CREATE TABLE T1( [ID] [int] IDENTITY NOT NULL,
                 [Filler] [char](8000) NULL,
                 PRIMARY KEY CLUSTERED ([ID] ASC))

पूछताछ

SELECT TOP 10 *
FROM T1
ORDER BY ID DESC

स्कैन दिशा के साथ एक आदेशित स्कैन का उपयोग करता है BACKWARDजैसा कि निष्पादन योजना में देखा जा सकता है। इसमें थोड़ा अंतर है लेकिन वर्तमान में केवल FORWARDस्कैन को ही समानांतर किया जा सकता है।

योजना

हालाँकि यह तार्किक विखंडन के संदर्भ में एक बड़ा बदलाव ला सकता है । यदि अनुक्रमणिका कुंजी अवरोही के साथ बनाई गई है, लेकिन नई पंक्तियों को आरोही प्रमुख मूल्यों के साथ जोड़ा गया है तो आप तार्किक क्रम से बाहर हर पृष्ठ के साथ समाप्त हो सकते हैं। यह तालिका को स्कैन करते समय पढ़े जाने वाले IO के आकार को गंभीर रूप से प्रभावित कर सकता है और यह कैश में नहीं है।

विखंडन परिणाम देखें

                    avg_fragmentation                    avg_fragment
name   page_count   _in_percent         fragment_count   _size_in_pages
------ ------------ ------------------- ---------------- ---------------
T1     1000         0.4                 5                200
T2     1000         99.9                1000             1

नीचे स्क्रिप्ट के लिए

/*Uses T1 definition from above*/
SET NOCOUNT ON;

CREATE TABLE T2( [ID] [int] IDENTITY NOT NULL,
                 [Filler] [char](8000) NULL,
                 PRIMARY KEY CLUSTERED ([ID] DESC))

BEGIN TRAN

GO
INSERT INTO T1 DEFAULT VALUES
GO 1000
INSERT INTO T2 DEFAULT VALUES
GO 1000

COMMIT

SELECT object_name(object_id) AS name, 
       page_count, 
       avg_fragmentation_in_percent, 
       fragment_count, 
       avg_fragment_size_in_pages 
FROM 
sys.dm_db_index_physical_stats(db_id(), object_id('T1'), 1, NULL, 'DETAILED') 
WHERE  index_level = 0 
UNION ALL 
SELECT object_name(object_id) AS name, 
       page_count, 
       avg_fragmentation_in_percent, 
       fragment_count, 
       avg_fragment_size_in_pages 
FROM 
sys.dm_db_index_physical_stats(db_id(), object_id('T2'), 1, NULL, 'DETAILED') 
WHERE  index_level = 0 

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

SELECT page_id,
       [ID],
       geometry::Point(page_id, [ID], 0).STBuffer(4)
FROM   T1
       CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
UNION ALL
SELECT page_id,
       [ID],
       geometry::Point(page_id, [ID], 0).STBuffer(4)
FROM   T2
       CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )

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


इस बेहतरीन TIP के लिए मार्टिन का शुक्रिया, इसने वास्तव में रैंक क्वेरीज़ में मेरी मदद की
TheGameiswar

मुझे आश्चर्य है कि अगर मेरे पास एक अवरोही सूचकांक है, तो mytable से mycolumn का चयन करें जहां indexed_column = \ @myvalue तब तेज होता है जब \ @myvalue उस मामले की तुलना में अधिकतम संभव मान के करीब होता है जब \ @myvalue न्यूनतम संभव मान पर बंद हो जाता है।
लाजोस अरपाड

@LajosArpad क्यों तेज होगा? B पेड़ संतुलित पेड़ हैं। पेड़ की गहराई दोनों के लिए समान है।
मार्टिन स्मिथ

@ मर्टिनस्मिथ गहराई समान है, लेकिन मुझे संदेह है कि भाई-बहनों के आदेश से कोई फर्क नहीं पड़ेगा
लाजोस अरपाड

@MartinSmith, अगर भाई-बहनों के आदेश में प्रदर्शन में थोड़ा सा भी अंतर है, तो लाखों चयनों को जोड़ना होगा, न कि बहुआयामी जुड़ाव का उल्लेख करना।
लाजोस अरपाड

8

सॉर्ट क्रम तब मायने रखता है जब आप बहुत सारे सॉर्ट किए गए डेटा को पुनः प्राप्त करना चाहते हैं, न कि व्यक्तिगत रिकॉर्ड।

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

जब यह बात करता है तो @Quassnoi इसका शानदार उदाहरण प्रदान करता है।

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