यदि एक VARCHAR (MAX) कॉलम को एक इंडेक्स में शामिल किया जाता है, तो क्या पूरे मूल्य को हमेशा इंडेक्स पेज (एस) में संग्रहीत किया जाता है?


12

मैं इस सवाल से प्रेरित होकर जिज्ञासा से बाहर पूछ रहा हूं ।

हम जानते हैं कि VARCHAR(MAX)8000 बाइट्स से अधिक मूल्य पंक्तियों में संग्रहीत नहीं किए जाते हैं, लेकिन अलग-अलग एलओबी पृष्ठों में। बाद में इस तरह के मूल्य के साथ एक पंक्ति को पुनः प्राप्त करने के लिए दो या अधिक तार्किक आईओ संचालन की आवश्यकता होती है (अनिवार्य रूप से, अन्यथा एक से अधिक सैद्धांतिक रूप से आवश्यक होगी)।

हम एक VARCHAR(MAX)कॉलम जोड़ सकते हैं , जैसा कि INCLUDEडी, एक अद्वितीय सूचकांक में, जैसा कि जुड़े हुए प्रश्न में दिखाया गया है। यदि इस कॉलम में ऐसे मान हैं जो 8000 बाइट्स से अधिक हैं, तो क्या ऐसे मान अभी भी इंडेक्स लीफ पेजों में "इनलाइन" संग्रहीत किए जाएंगे, या उन्हें भी LOB पृष्ठों में ले जाया जाएगा?

जवाबों:


16

8000 बाइट्स से अधिक के मान "इनलाइन" संग्रहीत नहीं किए जा सकते। वे LOB पृष्ठों पर संग्रहीत हैं। आप इसे sysinos_db_index_physical_stats के साथ देख सकते हैं । एक साधारण तालिका से शुरुआत करें:

USE tempdb;

DROP TABLE IF EXISTS #LOB_FOR_ME;

CREATE TABLE #LOB_FOR_ME (
ID BIGINT,
MAX_VERNON_WAS_HERE VARCHAR(MAX) 
);

CREATE INDEX IX ON #LOB_FOR_ME (ID) INCLUDE (MAX_VERNON_WAS_HERE);

अब VARCHAR(MAX)कॉलम के लिए 8000 बाइट्स लेने वाले मानों के साथ कुछ पंक्तियाँ डालें और DMF देखें:

USE tempdb;

INSERT INTO #LOB_FOR_ME
SELECT 1, REPLICATE('Z', 8000)
FROM master..spt_values;

SELECT index_level, index_type_desc, alloc_unit_type_desc, page_count, record_count
FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('#LOB_FOR_ME'), 2, NULL , 'DETAILED'); 

सूचकांक में कोई LOB पृष्ठ नहीं हैं:

╔═════════════╦════════════════════╦══════════════════════╦════════════╦══════════════╗
 index_level   index_type_desc    alloc_unit_type_desc  page_count  record_count 
╠═════════════╬════════════════════╬══════════════════════╬════════════╬══════════════╣
           0  NONCLUSTERED INDEX  IN_ROW_DATA                 2540          2540 
           1  NONCLUSTERED INDEX  IN_ROW_DATA                   18          2540 
           2  NONCLUSTERED INDEX  IN_ROW_DATA                    1            18 
╚═════════════╩════════════════════╩══════════════════════╩════════════╩══════════════╝

लेकिन अगर मैं 8001 बाइट लेने वाले मानों के साथ पंक्तियाँ जोड़ता हूँ:

USE tempdb;

INSERT INTO #LOB_FOR_ME
SELECT 2, REPLICATE(CAST('Z' AS VARCHAR(MAX)), 8001)
FROM master..spt_values;

SELECT index_level, index_type_desc, alloc_unit_type_desc, page_count, record_count
FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('#LOB_FOR_ME'), 2, NULL , 'DETAILED'); 

अब मेरे पास हर पंक्ति के लिए अनुक्रमणिका में 1 LOB पृष्ठ है जिसे मैंने अभी डाला है:

╔═════════════╦════════════════════╦══════════════════════╦════════════╦══════════════╗
 index_level   index_type_desc    alloc_unit_type_desc  page_count  record_count 
╠═════════════╬════════════════════╬══════════════════════╬════════════╬══════════════╣
           0  NONCLUSTERED INDEX  IN_ROW_DATA                 2556          5080 
           1  NONCLUSTERED INDEX  IN_ROW_DATA                   18          2556 
           2  NONCLUSTERED INDEX  IN_ROW_DATA                    1            18 
           0  NONCLUSTERED INDEX  LOB_DATA                    2540          2540 
╚═════════════╩════════════════════╩══════════════════════╩════════════╩══════════════╝

आप इसे SET STATISTICS IO ON;और सही क्वेरी के साथ भी देख सकते हैं । निम्नलिखित प्रश्न पर विचार करें जो केवल 8000 बाइट वाली पंक्तियों को देखता है:

SELECT SUM(LEN(MAX_VERNON_WAS_HERE))
FROM #LOB_FOR_ME
WHERE ID = 1;

निष्पादित करने पर परिणाम:

स्कैन काउंट 1, लॉजिकल रीड 2560, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।

अगर मैं इसके बजाय 8001 बाइट्स वाली पंक्तियों की क्वेरी करूँ:

SELECT SUM(LEN(MAX_VERNON_WAS_HERE))
FROM #LOB_FOR_ME
WHERE ID = 2;

अब मैं लोब पढ़ता हूं:

स्कैन काउंट 1, लॉजिकल रीड 20, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड 5080, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।

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