समस्या
इस लेख में, हम तालिका विभाजन के प्रदर्शन पर ध्यान देंगे। तालिका विभाजन की सबसे सरल व्याख्या को बड़ी तालिकाओं को छोटे में विभाजित करना कहा जा सकता है। यह विषय मापनीयता और प्रबंधनीयता प्रदान करता है।
SQL सर्वर में तालिका विभाजन क्या है?
मान लीजिए कि हमारे पास एक मेज है और यह दिन-ब-दिन बढ़ती जाती है। इस मामले में, तालिका कुछ समस्याएं पैदा कर सकती है जिन्हें नीचे परिभाषित चरणों द्वारा हल करने की आवश्यकता है:
- इस तालिका को बनाए रखें। इसमें लंबा समय लगेगा और अधिक संसाधनों (सीपीयू, आईओ आदि) की खपत होगी।
- बैक अप लें।
- लॉक समस्याएं।
उपर्युक्त कारणों से, हमें तालिका विभाजन की आवश्यकता है। इस दृष्टिकोण के निम्नलिखित लाभ हैं:
- प्रबंधन क्षमता:यदि हम तालिका को अलग करते हैं, तो हम तालिका के प्रत्येक विभाजन का प्रबंधन कर सकते हैं। उदाहरण के लिए, हम टेबल का केवल एक ही पार्टिशन बना सकते हैं।
- संग्रह करने की क्षमता:तालिका के कुछ विभाजन केवल इसी कारण से उपयोग किए जाते हैं। हमें तालिका के इस विभाजन का बैकअप लेने की आवश्यकता नहीं है। हम फ़ाइल समूह बैकअप का उपयोग कर सकते हैं और केवल तालिका के विभाजन को बदलकर इसका बैकअप ले सकते हैं।
- क्वेरी प्रदर्शन:SQL सर्वर क्वेरी ऑप्टिमाइज़र विभाजन उन्मूलन का उपयोग करने का निर्णय लेता है। इसका अर्थ है कि SQL सर्वर तालिका के असंबंधित विभाजन के लिए कोई खोज नहीं करता है।
SQL सर्वर में लंबवत और क्षैतिज तालिका विभाजन
तालिका विभाजन एक सामान्य अवधारणा है। कई विभाजन प्रकार हैं जो विशेष मामलों के लिए काम करते हैं। सबसे आवश्यक और व्यापक रूप से उपयोग किए जाने वाले दो दृष्टिकोण हैं:लंबवत विभाजन और क्षैतिज विभाजन।
प्रत्येक प्रकार की विशिष्टता कॉलम और पंक्तियों से युक्त संरचना के रूप में तालिका के सार को दर्शाती है:
• लंबवत विभाजन तालिका को स्तंभों में विभाजित करता है।
• क्षैतिज विभाजन तालिका को पंक्तियों में विभाजित करता है।
सबसे विशिष्ट उदाहरण को विभाजित करने वाली ऊर्ध्वाधर तालिका कर्मचारियों की एक तालिका है जिसमें उनके विवरण - नाम, ईमेल, फोन नंबर, पते, जन्मदिन, व्यवसाय, वेतन, और अन्य सभी जानकारी की आवश्यकता हो सकती है। ऐसे डेटा का एक हिस्सा गोपनीय होता है। इसके अलावा, ज्यादातर मामलों में, ऑपरेटरों को केवल नाम और ईमेल पते जैसे कुछ बुनियादी डेटा की आवश्यकता होती है।
लंबवत विभाजन हाथ में आवश्यक डेटा के साथ कई "संकीर्ण" टेबल बनाता है। प्रश्न केवल एक विशिष्ट भाग को लक्षित करते हैं। इस तरह, व्यवसाय लोड को कम करते हैं, कार्यों में तेजी लाते हैं, और सुनिश्चित करते हैं कि गोपनीय डेटा प्रकट नहीं होगा।
क्षैतिज तालिका विभाजन के परिणामस्वरूप एक सामान्य तालिका को कई छोटे में विभाजित किया जाता है, जहां प्रत्येक कण तालिका में स्तंभों की संख्या समान होती है, लेकिन पंक्तियों की संख्या कम होती है। यह कालानुक्रमिक डेटा के साथ अत्यधिक तालिकाओं के लिए एक मानक दृष्टिकोण है।
उदाहरण के लिए, पूरे वर्ष के डेटा वाली तालिका को प्रत्येक माह या सप्ताह के लिए छोटे वर्गों में विभाजित किया जा सकता है। फिर, क्वेरी केवल एक विशिष्ट छोटी तालिका से संबंधित होगी। क्षैतिज विभाजन डेटा वॉल्यूम के लिए उनकी वृद्धि के साथ मापनीयता में सुधार करता है। विभाजित टेबल छोटी और संसाधित करने में आसान रहेंगी।
SQL सर्वर में किसी भी तालिका विभाजन पर सावधानी से विचार किया जाना चाहिए। कभी-कभी आपको एक साथ कई विभाजित तालिकाओं से डेटा का अनुरोध करना पड़ता है, और फिर आपको प्रश्नों में जॉइन की आवश्यकता होगी। इसके अलावा, ऊर्ध्वाधर विभाजन के परिणामस्वरूप अभी भी बड़ी तालिकाएँ हो सकती हैं, और आपको उन्हें और अधिक विभाजित करना होगा। अपने काम में, आपको अपने विशिष्ट व्यावसायिक उद्देश्यों के लिए निर्णयों पर भरोसा करना चाहिए।
अब जब हमने SQL सर्वर में तालिका विभाजन की अवधारणा को स्पष्ट कर दिया है, तो यह प्रदर्शन के लिए आगे बढ़ने का समय है।
हम किसी भी टी-एसक्यूएल स्क्रिप्ट से बचने जा रहे हैं और एसक्यूएल सर्वर विभाजन विज़ार्ड के साथ सभी तालिका विभाजन चरणों को संभालेंगे।
SQL डेटाबेस विभाजन बनाने के लिए आपको क्या चाहिए?
- WideWorldImporters नमूना डेटाबेस
- एसक्यूएल सर्वर 2017 डेवलपर संस्करण
नीचे दी गई छवि हमें दिखाती है कि तालिका विभाजन को कैसे डिज़ाइन किया जाए। हम वर्षों के आधार पर एक तालिका विभाजन करेंगे और विभिन्न फ़ाइल समूहों का पता लगाएंगे।
इस चरण में, हम दो फ़ाइल समूह (FG_2013, FG_2014) बनाएंगे। डेटाबेस पर राइट-क्लिक करें और फिर फ़ाइलग्रुप टैब पर क्लिक करें।
अब, हम फाइल समूहों को नई पीडीएफ फाइलों से जोड़ेंगे।
हमारा डेटाबेस स्टोरेज स्ट्रक्चर टेबल पार्टिशनिंग के लिए तैयार है। हम उस तालिका का पता लगाएंगे जिसे हम विभाजित करना चाहते हैं और विभाजन बनाएँ विज़ार्ड प्रारंभ करें।
नीचे दिए गए स्क्रीनशॉट में, हम उस कॉलम का चयन करेंगे जिस पर हम पार्टीशन फंक्शन लागू करना चाहते हैं। चयनित कॉलम "चालान दिनांक" है।
अगले दो स्क्रीन पर, हम एक पार्टीशन फंक्शन और एक पार्टीशन स्कीम को नाम देंगे।
एक विभाजन फ़ंक्शन परिभाषित करेगा कि [बिक्री] के लिए विभाजन कैसे करें। [चालान] इनवॉइस दिनांक कॉलम के आधार पर पंक्तियों।
एक विभाजन योजना बिक्री के लिए मानचित्रों को परिभाषित करेगी। फ़ाइल समूह के लिए चालान पंक्तियाँ।
फ़ाइल समूहों में विभाजन असाइन करें और सीमाएँ निर्धारित करें।
बाएँ / दाएँ सीमा प्रत्येक सीमा मान अंतराल के पक्ष को परिभाषित करती है जो बाएँ या दाएँ हो सकता है। हम इस तरह की सीमाएँ निर्धारित करेंगे और एस्टिमेट स्टोरेज पर क्लिक करेंगे। यह विकल्प हमें सीमाओं में स्थित होने वाली पंक्तियों की संख्या के बारे में जानकारी प्रदान करता है।
और अंत में, हम तुरंत रन का चयन करेंगे और फिर अगला क्लिक करेंगे।
ऑपरेशन सफल होने के बाद, बंद करें पर क्लिक करें।
जैसा कि आप देख सकते हैं, हमारी Sales.Invoices तालिका को विभाजित कर दिया गया है। यह क्वेरी विभाजित तालिका का विवरण दिखाएगी।
SELECT
OBJECT_SCHEMA_NAME(pstats.object_id) AS SchemaName
,OBJECT_NAME(pstats.object_id) AS TableName
,ps.name AS PartitionSchemeName
,ds.name AS PartitionFilegroupName
,pf.name AS PartitionFunctionName
,CASE pf.boundary_value_on_right WHEN 0 THEN 'Range Left' ELSE 'Range Right' END AS PartitionFunctionRange
,CASE pf.boundary_value_on_right WHEN 0 THEN 'Upper Boundary' ELSE 'Lower Boundary' END AS PartitionBoundary
,prv.value AS PartitionBoundaryValue
,c.name AS PartitionKey
,CASE
WHEN pf.boundary_value_on_right = 0
THEN c.name + ' > ' + CAST(ISNULL(LAG(prv.value) OVER(PARTITION BY pstats.object_id ORDER BY pstats.object_id, pstats.partition_number), 'Infinity') AS VARCHAR(100)) + ' and ' + c.name + ' <= ' + CAST(ISNULL(prv.value, 'Infinity') AS VARCHAR(100))
ELSE c.name + ' >= ' + CAST(ISNULL(prv.value, 'Infinity') AS VARCHAR(100)) + ' and ' + c.name + ' < ' + CAST(ISNULL(LEAD(prv.value) OVER(PARTITION BY pstats.object_id ORDER BY pstats.object_id, pstats.partition_number), 'Infinity') AS VARCHAR(100))
END AS PartitionRange
,pstats.partition_number AS PartitionNumber
,pstats.row_count AS PartitionRowCount
,p.data_compression_desc AS DataCompression
FROM sys.dm_db_partition_stats AS pstats
INNER JOIN sys.partitions AS p ON pstats.partition_id = p.partition_id
INNER JOIN sys.destination_data_spaces AS dds ON pstats.partition_number = dds.destination_id
INNER JOIN sys.data_spaces AS ds ON dds.data_space_id = ds.data_space_id
INNER JOIN sys.partition_schemes AS ps ON dds.partition_scheme_id = ps.data_space_id
INNER JOIN sys.partition_functions AS pf ON ps.function_id = pf.function_id
INNER JOIN sys.indexes AS i ON pstats.object_id = i.object_id AND pstats.index_id = i.index_id AND dds.partition_scheme_id = i.data_space_id AND i.type <= 1 /* Heap or Clustered Index */
INNER JOIN sys.index_columns AS ic ON i.index_id = ic.index_id AND i.object_id = ic.object_id AND ic.partition_ordinal > 0
INNER JOIN sys.columns AS c ON pstats.object_id = c.object_id AND ic.column_id = c.column_id
LEFT JOIN sys.partition_range_values AS prv ON pf.function_id = prv.function_id AND pstats.partition_number = (CASE pf.boundary_value_on_right WHEN 0 THEN prv.boundary_id ELSE (prv.boundary_id+1) END)
WHERE pstats.object_id = OBJECT_ID('Sales.Invoices')
ORDER BY TableName, PartitionNumber;
एमएस SQL सर्वर विभाजन प्रदर्शन
हम एक ही तालिका के लिए विभाजित और गैर-विभाजित तालिका प्रदर्शन की तुलना करेंगे। ऐसा करने के लिए, नीचे दी गई क्वेरी का उपयोग करें और वास्तविक निष्पादन योजना शामिल करें को सक्रिय करें।
DECLARE @Dt as date = '20131231'
SELECT COUNT(InvoiceDate)
FROM [Sales].[Invoices]
where InvoiceDate < @Dt
जब हम निष्पादन योजना की जांच करते हैं, तो हमें पता चलता है कि इसमें "विभाजित", "वास्तविक विभाजन गणना", और "वास्तविक विभाजन एक्सेस" गुण शामिल हैं।
विभाजित संपत्ति इंगित करता है कि यह तालिका विभाजन के लिए सक्षम है।
वास्तविक विभाजन गणना संपत्ति विभाजन की कुल संख्या है जिसे SQL सर्वर इंजन द्वारा पढ़ा जाता है।
वास्तविक पार्टिशन एक्सेस किया गया संपत्ति SQL सर्वर इंजन द्वारा मूल्यांकन की गई विभाजन संख्या है। SQL सर्वर अन्य विभाजनों के लिए पहुँच को समाप्त कर देता है क्योंकि इसे विभाजन उन्मूलन कहा जाता है और क्वेरी प्रदर्शन पर लाभ प्राप्त करता है।
अब, गैर-विभाजित तालिका निष्पादन योजना को देखें।
इन दो निष्पादन योजनाओं के बीच मुख्य अंतर है पंक्तियों की संख्या पढ़ें क्योंकि यह गुण इंगित करता है कि इस क्वेरी के लिए कितनी पंक्तियाँ पढ़ी जाती हैं। जैसा कि आप नीचे दिए गए संपीड़न चार्ट से देख सकते हैं, विभाजित तालिका मान बहुत कम हैं। इस कारण से, यह कम IO की खपत करेगा।
इसके बाद, क्वेरी चलाएँ और निष्पादन योजना की जाँच करें।
DECLARE @DtBeg as date = '20140502'
DECLARE @DtEnd as date = '20140701'
SELECT COUNT(InvoiceDate)
FROM [Sales].[Invoices]
where InvoiceDate between @DtBeg and @DtEnd
विभाजन-स्तर लॉक वृद्धि
लॉक एस्केलेशन एक तंत्र है जिसका उपयोग SQL सर्वर लॉक मैनेजर द्वारा किया जाता है। यह वस्तुओं के स्तर को लॉक करने की व्यवस्था करता है। जब लॉक की जाने वाली पंक्तियों की संख्या बढ़ जाती है, तो लॉक मैनेजर लॉकिंग ऑब्जेक्ट को बदल देता है। यह लॉक एस्केलेशन का पदानुक्रम स्तर है "पंक्ति -> पृष्ठ -> तालिका -> डेटाबेस"। लेकिन, विभाजित तालिका में, हम एक विभाजन को लॉक कर सकते हैं क्योंकि यह समवर्ती और प्रदर्शन को बढ़ाता है। लॉक एस्केलेशन का डिफ़ॉल्ट स्तर SQL सर्वर में "टेबल" है।
नीचे दिए गए UPDATE स्टेटमेंट का उपयोग करके क्वेरी को निष्पादित करें।
BEGIN TRAN
DECLARE @Dt as date = '20131221'
UPDATE [Sales].[Invoices] SET CreditNoteReason = 'xxx' where InvoiceDate < @Dt
SP_LOCK
लाल बॉक्स एक विशेष लॉक को परिभाषित करता है जो यह सुनिश्चित करता है कि एक ही समय में एक ही संसाधन में कई अपडेट नहीं किए जा सकते हैं। यह चालान तालिका में होता है।
अब, हम Sales.Invoices तालिका को स्वचालित करने और क्वेरी को फिर से चलाने के लिए एस्केलेशन मोड सेट करेंगे।
ALTER TABLE Sales.Invoices SET (LOCK_ESCALATION = AUTO)
अब, लाल बॉक्स इंडेंट एक्सक्लूसिव लॉक को परिभाषित करता है जो पदानुक्रम में निचले कुछ संसाधनों पर अनुरोधित या अधिग्रहित अनन्य लॉक की सुरक्षा करता है। शीघ्र ही, यह लॉक स्तर हमें तालिकाओं के अन्य विभाजन को अद्यतन करने या हटाने की अनुमति देता है। इसका मतलब है कि हम एक और अद्यतन शुरू कर सकते हैं या तालिका के अन्य विभाजन को सम्मिलित कर सकते हैं।
पिछली पोस्टों में, हमने टेबल पार्टिशनिंग के बीच स्विच करने के मुद्दे का भी पता लगाया और वॉकथ्रू प्रदान किया। यदि आप इन मामलों से निपटते हैं तो यह जानकारी आपके लिए मददगार हो सकती है। अधिक जानकारी के लिए लेख देखें।
संदर्भ
- लॉक मोड
- विभाजित टेबल और इंडेक्स