क्या बी-ट्री एक क्लस्टर इंडेक्स के साथ SQL सर्वर टेबल से डेटा को हटाने के दौरान फिर से संतुलित है?


10

मैं प्राथमिक कुंजी पर एक संकुल सूचकांक के साथ एक SQL सर्वर डेटाबेस में एक तालिका है। तालिका में 1 मिलियन पंक्तियाँ हैं। यदि मैं तालिका से 10K पंक्तियों को हटाता हूं, तो क्या डिलीट ऑपरेशन के दौरान इंडेक्स का पुनर्गठन किया जाता है?

विलोपन ऑपरेशन संग्रहीत कार्यविधि का हिस्सा है। एक समय में, एक से अधिक क्लाइंट संग्रहीत कार्यविधि को निष्पादित कर सकते हैं, हालांकि प्रत्येक व्यक्तिगत रन हटा देगा यह पंक्तियों का अपना सेट है (विशिष्ट रूप से प्राथमिक कुंजी द्वारा पहचाना गया)। जब कई क्लाइंट कार्यविधि निष्पादित करते हैं, तो मुझे कुंजी लॉक (प्रकार U) पर ब्लॉक करना होता है। अवरोधक लॉक एक ही तालिका से एक पंक्ति के अंतर्गत आता है और यह समवर्ती चल रहे लेन-देन में से किसी का हिस्सा नहीं है। इसमें कोई अवरोध नहीं होना चाहिए क्योंकि प्रत्येक रन पंक्तियों के अपने सेट को हटाने की कोशिश कर रहा है। लॉक एस्केलेशन बंद होते ही नहीं हो रहा है।

मुझे संदेह है, विलोपन कार्रवाई को फिर से संतुलित करने के लिए सूचकांक का कारण होना चाहिए और इसलिए पुनर्गठन प्रक्रिया के दौरान यह तालिका की किसी भी पंक्ति पर मुख्य लॉक ले सकता है।

मैं वास्तव में इस पर किसी भी राय की सराहना करूंगा।


अच्छा प्रश्न और अच्छा अनुमान। हां, जब आप रिकॉर्ड हटाते हैं, तो सूचकांक फिर से बनाया जाता है। पुनर्निर्माण प्रक्रिया के दौरान तालिका लॉक है और अन्य उपयोगकर्ता उस तालिका तक नहीं पहुंच पाएंगे। stackoverflow.com/questions/6309614/…
कुमार हर्ष

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

2
जब डिलीट होता है तो यह "छेद" बनाता है या आप कह सकते हैं कि डेटा को क्लस्टर इंडेक्स से हटा दिया गया था। यह कम पृष्ठ घनत्व बना सकता है और इसे विखंडन माना जा सकता है। जब इंसर्ट CI पर होता है तो यह दाईं ओर रिकॉर्ड भर देगा और इसके कारण यह जगह कभी नहीं भर सकती है। लेकिन SQL सर्वर स्वतः इस स्थान को हटाने वाला नहीं है। इस स्थान को भरने के लिए आपको अनुक्रमणिका का पुनर्निर्माण या पुनर्गठन करना होगा। वहाँ कोई असंतुलन है जैसे
Shanky

1
@ संजय मैं नहीं देखता कि एक पेड़ में नोड्स के क्रम का पुनर्संतुलन के साथ क्या करना है। एक बी-पेड़ असंतुलित हो सकता है (या तो आवेषण या हटाए जाने के कारण)। नोड आदेश इन मामलों में नहीं बदलता है। यह सिर्फ एक असंतुलित पेड़ है।
ypercube y

1
@ संजय मुझे लगता है कि आपको कुछ MSSQL डॉक्स पढ़ने से फायदा हो सकता है, क्योंकि मुझे लगता है कि आप जिस शब्दावली का उपयोग कर रहे हैं, वह आप और हम दोनों को भ्रमित कर रही है।
LowlyDBA

जवाबों:


3

शीर्षक में प्रश्न का उत्तर देने के लिए, चाहे बी-ट्री एक हटाए जाने के दौरान पुन: असंतुलित हो गया हो, इसका उत्तर कम से कम निम्नलिखित परीक्षण मामले में नहीं है।

निम्न डेमो कमांड चलाता है जो एक परीक्षण वातावरण के लिए सबसे अच्छा छोड़ दिया जाता है।

--create table and fill it
DROP TABLE IF EXISTS bunchesofints
CREATE TABLE bunchesofints (
thisisanint INT PRIMARY KEY CLUSTERED,
junkrow CHAR(1000) NOT NULL
)

INSERT dbo.bunchesofints
SELECT TOP 5000
ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) AS thisisanint,
REPLICATE('a',1000) AS junkrow
FROM sys.all_objects a1
CROSS JOIN sys.all_objects a2


--with this query we can see all the non-leaf pages of the b-tree, plus the IAM
SELECT allocated_page_page_id, page_type_desc, page_level, is_allocated, next_page_page_id, previous_page_page_id
FROM sys.dm_db_database_page_allocations(DB_ID(),OBJECT_ID('dbo.bunchesofints'),NULL,NULL,'DETAILED')
WHERE page_type != 1
GO

--Ok, let's delete most of the rows
;WITH CTE AS (
    SELECT TOP (4500) *
    FROM dbo.bunchesofints
    ORDER BY thisisanint DESC
)

DELETE 
FROM CTE
GO

--Hmm, still have 3 non-leaf index pages
SELECT allocated_page_page_id, page_type_desc, page_level, is_allocated, next_page_page_id, previous_page_page_id
FROM sys.dm_db_database_page_allocations(DB_ID(),OBJECT_ID('dbo.bunchesofints'),NULL,NULL,'DETAILED')
WHERE page_type != 1



--So, where are the rows?
--please note the assumption that your test database has a single file.
DECLARE @firstindexpage INT, @lastindexpage INT, @db INT = DB_ID()
SELECT @firstindexpage = MIN(previous_page_page_id), @lastindexpage = MAX(next_page_page_id)
FROM sys.dm_db_database_page_allocations(DB_ID(),OBJECT_ID('dbo.bunchesofints'),NULL,NULL,'DETAILED')
WHERE page_type = 2 AND page_level = 1

DBCC PAGE(@db,1,@firstindexpage,3) WITH TABLERESULTS
DBCC PAGE(@db,1,@lastindexpage,3) WITH TABLERESULTS

यह डेमो दिखाता है कि एक डिलीट एक बहुत असंतुलित बी-ट्री का उत्पादन कर सकता है, जिसमें एक तरफ व्यावहारिक रूप से सभी डेटा होते हैं।


स्पष्ट और संक्षिप्त स्पष्टीकरण और डेमो कोड के लिए धन्यवाद। मैं यह कोशिश करूँगा। मैं इस उत्तर को स्वीकार करूंगा। मैं अभी भी यह पता लगाने की कोशिश कर रहा हूं कि पंक्तियों के सेट के असंतुष्ट सेट पर क्‍लस्‍टर इंडेक्‍स के साथ टेबल पर क्‍लोजिंग के कारण डिलीट क्‍यों होता है।
ज्येश
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.