अतिथि लेखक:डेरिक हैमर (@SQLHammer)
हाल ही में हारून बर्ट्रेंड ने हानिकारक, व्यापक SQL सर्वर प्रदर्शन मिथकों के बारे में ब्लॉग किया था। इस ब्लॉग श्रृंखला के विस्तार के रूप में, मैं इस आम मिथक का खंडन करने जा रहा हूँ:
मैनुअल पढ़ना
सीधे स्रोत पर जाकर, मैंने टेबल पर बुक्स ऑनलाइन लेख देखा जिसमें टेबल वेरिएबल शामिल हैं। भले ही लेख तालिका चर का उपयोग करने के लाभों का संदर्भ देता है, यह तथ्य कि वे 100% इन-मेमोरी हैं, स्पष्ट रूप से गायब है।
हालांकि, एक लापता सकारात्मक का मतलब नकारात्मक नहीं है। चूंकि इन-मेमोरी ओएलटीपी टेबल जारी किए गए थे, अब इन-मेमोरी प्रोसेसिंग के लिए बीओएल में बहुत अधिक दस्तावेज हैं। यहीं पर मुझे मेमोरी ऑप्टिमाइजेशन का उपयोग करके अस्थायी तालिका और तालिका चर को तेज़ बनाने पर यह लेख मिला।
पूरा लेख इस बात के इर्द-गिर्द घूमता है कि कैसे अपनी अस्थायी वस्तुओं को इन-मेमोरी OLTP सुविधा का उपयोग करने के लिए बनाया जाए, और यहीं से मुझे वह सकारात्मक मिला जिसकी मुझे तलाश थी।
"एक पारंपरिक तालिका चर tempdb डेटाबेस में एक तालिका का प्रतिनिधित्व करता है। बहुत तेज़ प्रदर्शन के लिए आप अपने तालिका चर को मेमोरी-ऑप्टिमाइज़ कर सकते हैं।"टेबल वैरिएबल इन-मेमोरी कंस्ट्रक्शन नहीं हैं। इन-मेमोरी तकनीक का उपयोग करने के लिए आपको स्पष्ट रूप से एक प्रकार को परिभाषित करना होगा जो स्मृति अनुकूलित है और उस प्रकार का उपयोग अपने तालिका चर को परिभाषित करने के लिए करें।
साबित करें
दस्तावेज़ीकरण एक बात है लेकिन इसे अपनी आँखों से देखना बिलकुल दूसरी बात है। मुझे पता है कि अस्थायी टेबल tempdb में ऑब्जेक्ट बनाते हैं और डिस्क पर डेटा लिखेंगे। पहले मैं आपको दिखाऊंगा कि अस्थायी तालिकाओं के लिए कैसा दिखता है और फिर मैं उसी पद्धति का उपयोग इस परिकल्पना को मान्य करने के लिए करूंगा कि तालिका चर उसी तरह कार्य करते हैं।
लॉग रिकॉर्ड विश्लेषण
यह क्वेरी मुझे एक स्वच्छ प्रारंभिक बिंदु देने के लिए एक CHECKPOINT चलाएगी और फिर लॉग रिकॉर्ड की संख्या और लॉग में मौजूद लेन-देन के नाम दिखाएगी।
USE tempdb; GO CHECKPOINT; GO SELECT COUNT(*) [Count] FROM sys.fn_dblog (NULL, NULL); SELECT [Transaction Name] FROM sys.fn_dblog (NULL, NULL) WHERE [Transaction Name] IS NOT NULL;
टी-एसक्यूएल को बार-बार चलाने से लगातार तीन रिकॉर्ड गिनती होती है SQL सर्वर 2016 SP1 पर।
यह एक अस्थायी तालिका बनाता है और ऑब्जेक्ट रिकॉर्ड प्रदर्शित करता है, यह साबित करता है कि यह tempdb में एक वास्तविक वस्तु है।
USE tempdb; GO DROP TABLE IF EXISTS #tmp; GO CREATE TABLE #tmp (id int NULL); SELECT name FROM sys.objects o WHERE is_ms_shipped = 0;
अब मैं फिर से लॉग रिकॉर्ड दिखाऊंगा। मैं CHECKPOINT कमांड को दोबारा नहीं चलाऊंगा।
इक्कीस लॉग रिकॉर्ड लिखे गए, यह साबित करते हुए कि ये ऑन-डिस्क राइट हैं, और हमारी क्रिएट टेबल इन लॉग रिकॉर्ड में स्पष्ट रूप से शामिल है।
इन परिणामों की तालिका चरों से तुलना करने के लिए, मैं CHECKPOINT चलाकर और फिर तालिका चर बनाकर, नीचे T-SQL को क्रियान्वित करके प्रयोग को रीसेट कर दूंगा।
USE tempdb; GO DECLARE @var TABLE (id int NULL); SELECT name FROM sys.objects o WHERE is_ms_shipped = 0;
एक बार फिर हमारे पास एक नया ऑब्जेक्ट रिकॉर्ड है। हालांकि, इस बार नाम अस्थायी तालिकाओं की तुलना में अधिक यादृच्छिक है।
बयासी नए लॉग रिकॉर्ड और लेन-देन के नाम हैं जो साबित करते हैं कि मेरा चर लॉग में लिखा जा रहा है, और इसलिए, डिस्क पर।
वास्तव में स्मृति में है
अब मेरे लिए लॉग रिकॉर्ड को गायब करने का समय आ गया है।
मैंने एक इन-मेमोरी OLTP फाइलग्रुप बनाया और फिर एक मेमोरी ऑप्टिमाइज़्ड टेबल टाइप बनाया।
USE Test; GO CREATE TYPE dbo.inMemoryTableType AS TABLE ( id INT NULL INDEX ix1 ) WITH (MEMORY_OPTIMIZED = ON); GO
मैंने CHECKPOINT को फिर से क्रियान्वित किया और फिर मेमोरी अनुकूलित तालिका बनाई।
USE Test; GO DECLARE @var dbo.inMemoryTableType; INSERT INTO @var (id) VALUES (1) SELECT * from @var; GO
लॉग की समीक्षा करने के बाद, मुझे कोई लॉग गतिविधि नहीं दिखाई दी। यह विधि वास्तव में 100% इन-मेमोरी है।
ले लो
तालिका चर tempdb का उपयोग उसी तरह करते हैं जैसे अस्थायी तालिकाएँ tempdb का उपयोग करती हैं। तालिका चर इन-मेमोरी निर्माण नहीं हैं, लेकिन यदि आप मेमोरी अनुकूलित उपयोगकर्ता परिभाषित तालिका प्रकारों का उपयोग करते हैं तो वे बन सकते हैं। अक्सर मुझे टेबल वेरिएबल की तुलना में अस्थायी टेबल बहुत बेहतर विकल्प लगता है। इसका मुख्य कारण यह है कि तालिका चर में आँकड़े नहीं होते हैं और, SQL सर्वर संस्करण और सेटिंग्स के आधार पर, पंक्ति अनुमान 1 पंक्ति या 100 पंक्तियों के रूप में काम करते हैं। दोनों ही मामलों में ये अनुमान हैं और आपकी क्वेरी अनुकूलन प्रक्रिया में गलत सूचना के हानिकारक अंश बन जाते हैं।
ध्यान दें कि इनमें से कुछ फीचर अंतर समय के साथ बदल सकते हैं - उदाहरण के लिए, SQL सर्वर के हाल के संस्करणों में, आप इनलाइन इंडेक्स सिंटैक्स का उपयोग करके टेबल वैरिएबल पर अतिरिक्त इंडेक्स बना सकते हैं। निम्न तालिका में तीन अनुक्रमणिका हैं; प्राथमिक कुंजी (डिफ़ॉल्ट रूप से संकुलित), और दो गैर-संकुल सूचकांक:
DECLARE @t TABLE ( a int PRIMARY KEY, b int, INDEX x (b, a DESC), INDEX y (b DESC, a) );
DBA स्टैक एक्सचेंज पर एक बढ़िया उत्तर है जहाँ मार्टिन स्मिथ तालिका चर और #temp तालिकाओं के बीच के अंतरों का विस्तृत विवरण देता है:
- SQL सर्वर में अस्थायी तालिका और तालिका चर के बीच क्या अंतर है?