जैसा कि किसी भी अनुभवी उत्पादन डीबीए को पता है, आप पर डेटाबेस प्रदर्शन समस्याओं का जल्द से जल्द निदान करने और उन्हें कम करने के लिए अक्सर महत्वपूर्ण दबाव होता है। यहां तीन चीजें हैं जिनका आप लाभ उठा सकते हैं, जो आपके कार्यभार और बुनियादी ढांचे के आधार पर आपके डेटाबेस के प्रदर्शन पर बहुत ही सकारात्मक सकारात्मक प्रभाव डाल सकता है।
बेसिक रो स्टोर इंडेक्स ट्यूनिंग
अधिकांश SQL सर्वर इंस्टेंसेस जिनका मैंने अपने करियर में सामना किया है, उनमें कुछ अपेक्षाकृत आसान रो स्टोर इंडेक्स ट्यूनिंग के अवसर हैं। पंक्ति स्टोर इंडेक्स ट्यूनिंग के बारे में एक अच्छी बात यह है कि यह अक्सर डीबीए के रूप में आपके प्रत्यक्ष नियंत्रण में होता है, विशेष रूप से क्वेरी या संग्रहीत प्रक्रिया ट्यूनिंग की तुलना में, जो अक्सर डेवलपर्स या 3 पार्टी विक्रेताओं के नियंत्रण में होते हैं।
कुछ डीबीए किसी भी इंडेक्स ट्यूनिंग (विशेष रूप से 3 पार्टी डेटाबेस पर) करने के लिए अनिच्छुक हैं क्योंकि वे कुछ तोड़ने या डेटाबेस या एप्लिकेशन के लिए विक्रेता समर्थन को खतरे में डालने के बारे में चिंतित हैं। जाहिर है, आपको 3 पार्टी डेटाबेस के साथ अधिक सावधान रहने की जरूरत है, और किसी भी इंडेक्स को बदलने से पहले विक्रेता तक पहुंचने का प्रयास करें, लेकिन कुछ स्थितियों में, आपके पास कोई अन्य व्यवहार्य विकल्प नहीं हो सकता है (समस्या पर तेज हार्डवेयर और भंडारण को फेंकने के अलावा) )।
यदि आप अपने उदाहरण या डेटाबेस पर कुछ आसान अनुक्रमणिका ट्यूनिंग अवसर प्राप्त कर सकते हैं, तो एक अच्छा विचार प्राप्त करने के लिए आप मेरी SQL सर्वर डायग्नोस्टिक सूचना क्वेरी से कुछ महत्वपूर्ण प्रश्न चला सकते हैं। आपको अनुपलब्ध अनुक्रमणिका अनुरोधों, अनुपलब्ध अनुक्रमणिका चेतावनियों, कम उपयोग किए गए या गैर-प्रयुक्त गैर-संकुल अनुक्रमणिकाओं और संभावित डेटा संपीड़न अवसरों की तलाश में रहना चाहिए।
उचित इंडेक्स ट्यूनिंग करने के लिए आपके कार्यभार का कुछ अनुभव, अच्छा निर्णय और ज्ञान होता है। उचित विश्लेषण किए बिना जल्दबाजी में कई इंडेक्स परिवर्तन करके लोगों को गलत इंडेक्स ट्यूनिंग करते देखना आम बात है।
यहाँ कुछ प्रश्न दिए गए हैं जिनका मैं डेटाबेस स्तर पर उपयोग करना पसंद करता हूँ:
-- Missing Indexes for current database by Index Advantage (Query 1) (Missing Indexes) SELECT DISTINCT CONVERT(decimal(18,2), user_seeks * avg_total_user_cost * (avg_user_impact * 0.01)) AS [index_advantage], migs.last_user_seek, mid.[statement] AS [Database.Schema.Table], mid.equality_columns, mid.inequality_columns, mid.included_columns, migs.unique_compiles, migs.user_seeks, migs.avg_total_user_cost, migs.avg_user_impact, OBJECT_NAME(mid.[object_id]) AS [Table Name], p.rows AS [Table Rows] FROM sys.dm_db_missing_index_group_stats AS migs WITH (NOLOCK) INNER JOIN sys.dm_db_missing_index_groups AS mig WITH (NOLOCK) ON migs.group_handle = mig.index_group_handle INNER JOIN sys.dm_db_missing_index_details AS mid WITH (NOLOCK) ON mig.index_handle = mid.index_handle INNER JOIN sys.partitions AS p WITH (NOLOCK) ON p.[object_id] = mid.[object_id] WHERE mid.database_id = DB_ID() AND p.index_id < 2 ORDER BY index_advantage DESC OPTION (RECOMPILE); ------ -- Look at index advantage, last user seek time, number of user seeks to help determine source and importance -- SQL Server is overly eager to add included columns, so beware -- Do not just blindly add indexes that show up from this query!!! -- Find missing index warnings for cached plans in the current database (Query 2) (Missing Index Warnings) -- Note: This query could take some time on a busy instance SELECT TOP(25) OBJECT_NAME(objectid) AS [ObjectName], cp.objtype, cp.usecounts, cp.size_in_bytes, query_plan FROM sys.dm_exec_cached_plans AS cp WITH (NOLOCK) CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp WHERE CAST(query_plan AS NVARCHAR(MAX)) LIKE N'%MissingIndex%' AND dbid = DB_ID() ORDER BY cp.usecounts DESC OPTION (RECOMPILE); ------ -- Helps you connect missing indexes to specific stored procedures or queries -- This can help you decide whether to add them or not -- Possible Bad NC Indexes (writes >= reads) (Query 3) (Bad NC Indexes) SELECT OBJECT_NAME(s.[object_id]) AS [Table Name], i.name AS [Index Name], i.index_id, i.is_disabled, i.is_hypothetical, i.has_filter, i.fill_factor, s.user_updates AS [Total Writes], s.user_seeks + s.user_scans + s.user_lookups AS [Total Reads], s.user_updates - (s.user_seeks + s.user_scans + s.user_lookups) AS [Difference] FROM sys.dm_db_index_usage_stats AS s WITH (NOLOCK) INNER JOIN sys.indexes AS i WITH (NOLOCK) ON s.[object_id] = i.[object_id] AND i.index_id = s.index_id WHERE OBJECTPROPERTY(s.[object_id],'IsUserTable') = 1 AND s.database_id = DB_ID() AND s.user_updates > (s.user_seeks + s.user_scans + s.user_lookups) AND i.index_id > 1 AND i.[type_desc] = N'NONCLUSTERED' AND i.is_primary_key = 0 AND i.is_unique_constraint = 0 AND i.is_unique = 0 ORDER BY [Difference] DESC, [Total Writes] DESC, [Total Reads] ASC OPTION (RECOMPILE); ------ -- Look for indexes with high numbers of writes and zero or very low numbers of reads -- Consider your complete workload, and how long your instance has been running -- Investigate further before dropping an index! -- Breaks down buffers used by current database by object (table, index) in the buffer cache (Query 4) (Buffer Usage) -- Note: This query could take some time on a busy instance SELECT OBJECT_NAME(p.[object_id]) AS [Object Name], p.index_id, CAST(COUNT(*)/128.0 AS DECIMAL(10, 2)) AS [Buffer size(MB)], COUNT(*) AS [BufferCount], p.[Rows] AS [Row Count], p.data_compression_desc AS [Compression Type] FROM sys.allocation_units AS a WITH (NOLOCK) INNER JOIN sys.dm_os_buffer_descriptors AS b WITH (NOLOCK) ON a.allocation_unit_id = b.allocation_unit_id INNER JOIN sys.partitions AS p WITH (NOLOCK) ON a.container_id = p.hobt_id WHERE b.database_id = CONVERT(int, DB_ID()) AND p.[object_id] > 100 AND OBJECT_NAME(p.[object_id]) NOT LIKE N'plan_%' AND OBJECT_NAME(p.[object_id]) NOT LIKE N'sys%' AND OBJECT_NAME(p.[object_id]) NOT LIKE N'xml_index_nodes%' GROUP BY p.[object_id], p.index_id, p.data_compression_desc, p.[Rows] ORDER BY [BufferCount] DESC OPTION (RECOMPILE); ------ -- Tells you what tables and indexes are using the most memory in the buffer cache -- It can help identify possible candidates for data compression
विलंबित स्थायित्व का उपयोग करना
विलंबित स्थायित्व सुविधा को SQL सर्वर 2014 में उत्पाद में जोड़ा गया था, इसलिए यह काफी समय से उपलब्ध है। विलंबित टिकाऊ लेन-देन कमिट एसिंक्रोनस होते हैं और लेन-देन की प्रतिबद्धता को पहले . के रूप में सफल बताते हैं लेन-देन के लिए लॉग रिकॉर्ड वास्तव में स्टोरेज सबसिस्टम को लिखे जाते हैं। विलंबित टिकाऊ लेन-देन वास्तव में तब तक टिकाऊ नहीं होते जब तक कि लेन-देन लॉग प्रविष्टियाँ डिस्क पर फ़्लश नहीं हो जातीं।
यह सुविधा SQL सर्वर के सभी संस्करणों में उपलब्ध है। इसके बावजूद, जब मैं क्लाइंट डेटाबेस को देखता हूं तो मुझे शायद ही कभी इसका उपयोग किया जाता है। विलंबित स्थायित्व कुछ डेटा हानि की संभावना को खोलता है, सबसे खराब स्थिति में पूरे लॉग बफर तक (जैसा कि पॉल रैंडल द्वारा समझाया गया है यहाँ), इसलिए यह निश्चित रूप से एक आरपीओ परिदृश्य के लिए उपयुक्त नहीं है जहां बिल्कुल कोई डेटा हानि स्वीकार्य नहीं है।
विलंबित स्थायित्व लेन-देन की विलंबता को कम करता है क्योंकि यह लॉग IO के समाप्त होने और क्लाइंट को नियंत्रण वापस करने की प्रतीक्षा नहीं करता है, और यह समवर्ती लेनदेन के लिए लॉकिंग और डिस्क विवाद को भी कम करता है। इन दो लाभों का अक्सर आपकी क्वेरी और एप्लिकेशन के प्रदर्शन पर बहुत ही सकारात्मक प्रभाव पड़ सकता है, जिसमें उपयुक्त बहुत ही लेखन-भारी कार्यभार होता है।
विलंबित स्थायित्व अक्सर भारी OLTP-प्रकार के वर्कलोड में मदद करेगा जिसमें बहुत बार-बार, छोटे लेखन लेनदेन होते हैं जहां आप लेनदेन लॉग फ़ाइल पर sys.dm_io_virtual_file_stats से उच्च फ़ाइल-स्तरीय लेखन विलंबता देख रहे हैं और/या आप उच्च WRITELOG sys से प्रतीक्षा कर रहे हैं। dm_os_wait_stats.
आप निम्न आदेश चलाकर आसानी से SQL सर्वर 2014 या नए को सभी लेनदेन (बिना कोड परिवर्तन के) के लिए विलंबित स्थायित्व का उपयोग करने के लिए बाध्य कर सकते हैं:
ALTER DATABASE AdventureWorks2014 SET DELAYED_DURABILITY = FORCED;
मेरे पास ऐसे ग्राहक हैं जो दिन के अलग-अलग समय (जैसे अनुसूचित ईटीएल या रखरखाव गतिविधि के दौरान) पर प्रोग्रामेटिक रूप से विलंबित स्थायित्व को चालू और बंद करते हैं। मेरे पास ऐसे ग्राहक भी हैं जो हर समय विलंबित स्थायित्व का उपयोग करते हैं क्योंकि उनके पास उपयुक्त कार्यभार और डेटा हानि जोखिम सहनशीलता है।
अंत में, मेरे पास ऐसे ग्राहक हैं जो कभी भी विलंबित स्थायित्व का उपयोग करने पर विचार नहीं करेंगे, या बस अपने कार्यभार के साथ इसकी आवश्यकता नहीं है। यदि आपको संदेह है कि आपका कार्यभार हो सकता है विलंबित स्थायित्व का उपयोग करने से लाभ, लेकिन आप संभावित डेटा हानि के बारे में चिंतित हैं, तो ऐसे अन्य विकल्प हैं जिन पर आप विचार कर सकते हैं।
SQL सर्वर 2016 SP1 में स्थायी लॉग बफ़र सुविधा एक विकल्प है, जहाँ आप एक NV-DIMM परसिस्टेंट मेमोरी डिवाइस पर होस्ट किए गए डायरेक्ट एक्सेस मोड (DAX) स्टोरेज वॉल्यूम पर दूसरी, 20MB ट्रांजेक्शन लॉग फ़ाइल बना सकते हैं। इस अतिरिक्त लेन-देन लॉग फ़ाइल का उपयोग लॉग के टेल को कैश करने के लिए किया जाता है, बाइट-स्तरीय एक्सेस के साथ जो पारंपरिक ब्लॉक-स्तरीय स्टोरेज स्टैक को बायपास करता है।
यदि आपको लगता है कि आपके कार्यभार को स्थायी लॉग बफर सुविधा का उपयोग करने से लाभ हो सकता है, तो आप यह देखने के लिए अस्थायी रूप से विलंबित स्थायित्व का उपयोग कर सकते हैं कि क्या आपके द्वारा NV-DIMM परसिस्टेंट मेमोरी पर पैसा खर्च करने से पहले आपके कार्यभार के साथ वास्तविक प्रदर्शन लाभ है या नहीं। स्थायी लॉग बफर सुविधा का उपयोग करने की आवश्यकता होगी।
tempdb को Intel Optane DC P4800X स्टोरेज में ले जाना
मुझे हाल ही के कई क्लाइंट्स के साथ बड़ी सफलता मिली है, जिन्होंने अपनी tempdb डेटाबेस फ़ाइलों को किसी अन्य प्रकार के स्टोरेज से एक लॉजिकल ड्राइव में स्थानांतरित कर दिया था, जो कि Intel Optane DC P4800X PCIe NVMe स्टोरेज कार्ड (एक सॉफ्टवेयर RAID 1 सरणी में) के एक जोड़े द्वारा समर्थित थी।पी>
ये स्टोरेज कार्ड 375GB, 750GB और 1.5TB क्षमता में उपलब्ध हैं (हालाँकि 1.5TB क्षमता बिल्कुल नई है और अभी भी इसे खोजना मुश्किल है)। उनके पास बहुत कम विलंबता (किसी भी प्रकार के NAND फ्लैश स्टोरेज से बहुत कम), कम कतार गहराई पर उत्कृष्ट यादृच्छिक I/O प्रदर्शन (NAND फ्लैश स्टोरेज से काफी बेहतर), बहुत भारी लेखन कार्यभार के तहत लगातार पढ़ने के प्रतिक्रिया समय के साथ है।पी>
उनके पास "राइट-इंटेंसिव" एंटरप्राइज NAND फ्लैश स्टोरेज की तुलना में उच्च लेखन सहनशक्ति है, और उनका प्रदर्शन खराब नहीं होता है क्योंकि वे पूर्ण होने के करीब हैं। ये विशेषताएँ इन कार्डों को कई भारी tempdb कार्यभार, विशेष रूप से भारी OLTP कार्यभार और उन स्थितियों के लिए बहुत उपयुक्त बनाती हैं जहाँ आप अपने उपयोगकर्ता डेटाबेस में RCSI का उपयोग कर रहे हैं (जो परिणामी संस्करण को tempdb पर संग्रहीत करता है)।
sys.dm_io_virtual_file_stats DMV से tempdb डेटा फ़ाइलों पर उच्च फ़ाइल-स्तरीय लेखन विलंबता देखना भी बहुत आम है, इसलिए अपनी tempdb डेटा फ़ाइलों को ऑप्टेन स्टोरेज में ले जाना उस समस्या को सीधे संबोधित करने का एक तरीका है, जो पारंपरिक की तुलना में तेज़ और आसान हो सकता है वर्कलोड ट्यूनिंग।
ऑप्टेन स्टोरेज कार्ड के लिए एक अन्य संभावित उपयोग आपके लेन-देन लॉग फ़ाइल (फाइलों) के लिए एक घर के रूप में है। आप SQL सर्वर के पुराने संस्करणों के साथ Optane संग्रहण का भी उपयोग कर सकते हैं (जब तक आपका OS और हार्डवेयर इसका समर्थन करते हैं)। यह विलंबित स्थायित्व (जिसके लिए SQL सर्वर 2014 की आवश्यकता है) का उपयोग करने या स्थायी लॉग बफर सुविधा (जिसके लिए SQL Server 2016 SP1 की आवश्यकता है) का उपयोग करने का एक संभावित विकल्प है।
निष्कर्ष
मैंने SQL सर्वर के साथ त्वरित प्रदर्शन जीत हासिल करने के लिए तीन तकनीकों पर चर्चा की:
- पारंपरिक पंक्ति स्टोर इंडेक्स ट्यूनिंग SQL सर्वर के सभी संस्करणों पर लागू होती है, और यह आपके शस्त्रागार में सबसे अच्छे टूल में से एक है।
- विलंबित स्थायित्व SQL सर्वर 2014 और नए में उपलब्ध है, और यह कुछ कार्यभार प्रकारों (और RPO आवश्यकताओं) के साथ बहुत फायदेमंद हो सकता है। स्थायी लॉग बफ़र SQL Server 2016 SP1 में उपलब्ध है, और यह डेटा हानि के खतरे के बिना, विलंबित स्थायित्व के समान लाभ देता है।
- कुछ प्रकार की डेटाबेस फ़ाइलों को Intel Optane संग्रहण में ले जाने से tempdb या उपयोगकर्ता डेटाबेस लेनदेन लॉग फ़ाइलों के साथ प्रदर्शन समस्याओं को कम करने में मदद मिल सकती है। आप SQL सर्वर के पुराने संस्करणों के साथ Optane संग्रहण का उपयोग कर सकते हैं, और इसके लिए किसी कोड या कॉन्फ़िगरेशन परिवर्तन की आवश्यकता नहीं है।