तालिका-मूल्यवान पैरामीटर SQL सर्वर 2008 के बाद से आसपास रहे हैं और SQL सर्वर को डेटा की कई पंक्तियों को भेजने के लिए एक उपयोगी तंत्र प्रदान करते हैं, एक एकल पैरामीटरयुक्त कॉल के रूप में एक साथ लाया जाता है। कोई भी पंक्तियाँ तब एक तालिका चर में उपलब्ध होती हैं जिसे तब मानक टी-एसक्यूएल कोडिंग में उपयोग किया जा सकता है, जो डेटा को फिर से तोड़ने के लिए विशेष प्रसंस्करण तर्क लिखने की आवश्यकता को समाप्त करता है। उनकी परिभाषा के अनुसार, तालिका-मूल्यवान पैरामीटर उपयोगकर्ता-परिभाषित तालिका प्रकार के लिए दृढ़ता से टाइप किए जाते हैं जो उस डेटाबेस के भीतर मौजूद होना चाहिए जहां कॉल किया जा रहा है। हालाँकि, दृढ़ता से टाइप किया गया वास्तव में सख्ती से "दृढ़ता से टाइप किया गया" नहीं है, जैसा कि आप उम्मीद करेंगे, क्योंकि यह लेख प्रदर्शित करने जा रहा है, और परिणामस्वरूप प्रदर्शन प्रभावित हो सकता है।
SQL सर्वर के साथ गलत तरीके से टाइप किए गए तालिका-मूल्यवान मापदंडों के संभावित प्रदर्शन प्रभावों को प्रदर्शित करने के लिए, हम निम्नलिखित संरचना के साथ एक उदाहरण उपयोगकर्ता-परिभाषित तालिका प्रकार बनाने जा रहे हैं:
CREATE TYPE dbo.PharmacyData AS TABLE ( Dosage int, Drug varchar(20), FirstName varchar(50), LastName varchar(50), AddressLine1 varchar(250), PhoneNumber varchar(50), CellNumber varchar(50), EmailAddress varchar(100), FillDate datetime );
फिर हमें एक .NET एप्लिकेशन की आवश्यकता होगी जो SQL सर्वर में डेटा पास करने के लिए इनपुट पैरामीटर के रूप में इस उपयोगकर्ता-परिभाषित तालिका प्रकार का उपयोग करने जा रहा है। हमारे एप्लिकेशन से तालिका-मूल्यवान पैरामीटर का उपयोग करने के लिए, डेटाटेबल ऑब्जेक्ट को आम तौर पर पॉप्युलेट किया जाता है और फिर पैरामीटर के मान के रूप में एक प्रकार के SqlDbType.Structured के साथ पास किया जाता है। डेटाटेबल को .NET कोड में कई तरीकों से बनाया जा सकता है, लेकिन टेबल बनाने का एक सामान्य तरीका निम्न जैसा कुछ है:
System.Data.DataTable DefaultTable = new System.Data.DataTable("@PharmacyData"); DefaultTable.Columns.Add("Dosage", typeof(int)); DefaultTable.Columns.Add("Drug", typeof(string)); DefaultTable.Columns.Add("FirstName", typeof(string)); DefaultTable.Columns.Add("LastName", typeof(string)); DefaultTable.Columns.Add("AddressLine1", typeof(string)); DefaultTable.Columns.Add("PhoneNumber", typeof(string)); DefaultTable.Columns.Add("CellNumber", typeof(string)); DefaultTable.Columns.Add("EmailAddress", typeof(string)); DefaultTable.Columns.Add("Date", typeof(DateTime));
आप निम्न प्रकार से इनलाइन परिभाषा का उपयोग करके डेटाटेबल भी बना सकते हैं:
System.Data.DataTable DefaultTable = new System.Data.DataTable("@PharmacyData") { Columns = { {"Dosage", typeof(int)}, {"Drug", typeof(string)}, {"FirstName", typeof(string)}, {"LastName", typeof(string)}, {"AddressLine1", typeof(string)}, {"PhoneNumber", typeof(string)}, {"CellNumber", typeof(string)}, {"EmailAddress", typeof(string)}, {"Date", typeof(DateTime)}, }, Locale = CultureInfo.InvariantCulture };
.NET में डेटाटेबल ऑब्जेक्ट की इन परिभाषाओं में से कोई भी, बनाए गए उपयोगकर्ता-परिभाषित डेटा प्रकार के लिए तालिका-मूल्यवान पैरामीटर के रूप में उपयोग किया जा सकता है, लेकिन विभिन्न स्ट्रिंग कॉलम के लिए टाइपऑफ़ (स्ट्रिंग) परिभाषा पर ध्यान दें; ये सभी "ठीक से" टाइप किए जा सकते हैं, लेकिन वे वास्तव में उपयोगकर्ता-परिभाषित डेटा प्रकार में लागू डेटा प्रकारों के लिए दृढ़ता से टाइप नहीं किए गए हैं। हम तालिका को यादृच्छिक डेटा के साथ पॉप्युलेट कर सकते हैं और इसे एक बहुत ही सरल चयन कथन के पैरामीटर के रूप में SQL सर्वर पर पास कर सकते हैं जो तालिका के रूप में ठीक उसी पंक्तियों को वापस करने जा रहा है, जिसे हमने पास किया था:
using (SqlCommand cmd = new SqlCommand("SELECT * FROM @tvp;", connection)) { var pList = new SqlParameter("@tvp", SqlDbType.Structured); pList.TypeName = "dbo.PharmacyData"; pList.Value = DefaultTable; cmd.Parameters.Add(pList); cmd.ExecuteReader().Dispose(); }
फिर हम डिबग ब्रेक का उपयोग कर सकते हैं ताकि हम निष्पादन के दौरान डिफॉल्टटेबल की परिभाषा का निरीक्षण कर सकें, जैसा कि नीचे दिखाया गया है:
हम देख सकते हैं कि स्ट्रिंग कॉलम के लिए MaxLength -1 पर सेट है, जिसका अर्थ है कि उन्हें TDS पर SQL सर्वर पर LOBs (बड़े ऑब्जेक्ट) के रूप में या अनिवार्य रूप से MAX डेटाटाइप किए गए कॉलम के रूप में पारित किया जा रहा है, और यह नकारात्मक तरीके से प्रदर्शन को प्रभावित कर सकता है। यदि हम .NET डेटाटेबल परिभाषा को उपयोगकर्ता द्वारा परिभाषित तालिका प्रकार की स्कीमा परिभाषा के अनुसार दृढ़ता से टाइप करने के लिए बदलते हैं और डिबग ब्रेक का उपयोग करके उसी कॉलम की अधिकतम लंबाई को देखते हैं:
System.Data.DataTable SchemaTable = new System.Data.DataTable("@PharmacyData") { Columns = { {new DataColumn() { ColumnName = "Dosage", DataType = typeof(int)} }, {new DataColumn() { ColumnName = "Drug", DataType = typeof(string), MaxLength = 20} }, {new DataColumn() { ColumnName = "FirstName", DataType = typeof(string), MaxLength = 50} }, {new DataColumn() { ColumnName = "LastName", DataType = typeof(string), MaxLength = 50} }, {new DataColumn() { ColumnName = "AddressLine1", DataType = typeof(string), MaxLength = 250} }, {new DataColumn() { ColumnName = "PhoneNumber", DataType = typeof(string), MaxLength = 50} }, {new DataColumn() { ColumnName = "CellNumber", DataType = typeof(string), MaxLength = 50} }, {new DataColumn() { ColumnName = "EmailAddress", DataType = typeof(string), MaxLength = 100} }, {new DataColumn() { ColumnName = "Date", DataType = typeof(DateTime)} }, }, Locale = CultureInfo.InvariantCulture };
अब हमारे पास कॉलम परिभाषाओं के लिए सही लंबाई है, और हम उन्हें SQL सर्वर पर TDS पर LOB के रूप में पास नहीं करेंगे।
आपको आश्चर्य हो सकता है कि यह प्रदर्शन को कैसे प्रभावित करता है? यह टीडीएस बफ़र्स की संख्या को प्रभावित करता है जो पूरे नेटवर्क में SQL सर्वर पर भेजे जाते हैं, और यह कमांड के लिए समग्र प्रसंस्करण समय को भी प्रभावित करता है।
दो डेटा तालिकाओं के लिए एक ही डेटा सेट का उपयोग करना, और SqlConnection ऑब्जेक्ट पर पुनर्प्राप्ति सांख्यिकी पद्धति का लाभ उठाना हमें एक ही SELECT कमांड पर कॉल के लिए ExecutionTime और BuffersSent सांख्यिकी मीट्रिक प्राप्त करने की अनुमति देता है, और पैरामीटर के रूप में केवल दो अलग-अलग डेटाटेबल परिभाषाओं का उपयोग करने की अनुमति देता है। और SqlConnection ऑब्जेक्ट की ResetStatistics विधि को कॉल करने से निष्पादन आँकड़ों को परीक्षणों के बीच साफ़ करने की अनुमति मिलती है।
GetSchemaTable परिभाषा प्रत्येक स्ट्रिंग कॉलम के लिए MaxLength को सही ढंग से निर्दिष्ट करती है जहां GetTable केवल टाइप स्ट्रिंग के कॉलम जोड़ता है जिसमें MaxLength मान -1 पर सेट होता है जिसके परिणामस्वरूप तालिका में डेटा की 861 पंक्तियों के लिए 100 अतिरिक्त टीडीएस बफर भेजे जा रहे हैं और एक रनटाइम दृढ़ता से टाइप की गई डेटाटेबल परिभाषा और 111 मिलीसेकंड के रन टाइम के लिए भेजे जा रहे केवल 250 बफ़र्स की तुलना में 158 मिलीसेकंड। हालांकि यह चीजों की भव्य योजना में ज्यादा नहीं लग सकता है, यह एक एकल कॉल, एकल निष्पादन है, और कई हजारों या लाखों ऐसे निष्पादन के लिए समय के साथ संचित प्रभाव है जहां लाभ जोड़ना शुरू होता है और एक ध्यान देने योग्य प्रभाव पड़ता है कार्यभार प्रदर्शन और थ्रूपुट पर।
जहां यह वास्तव में फर्क कर सकता है वह है क्लाउड कार्यान्वयन में जहां आप केवल गणना और भंडारण संसाधनों से अधिक के लिए भुगतान कर रहे हैं। Azure VM, SQL डेटाबेस, या AWS EC2 या RDS के लिए हार्डवेयर संसाधनों की निश्चित लागत होने के अलावा, प्रत्येक माह के लिए बिलिंग से निपटने वाले क्लाउड से नेटवर्क ट्रैफ़िक के लिए एक अतिरिक्त लागत होती है। तार के पार जाने वाले बफ़र्स को कम करने से समय के साथ समाधान के लिए TCO कम हो जाएगा, और इस बचत को लागू करने के लिए आवश्यक कोड परिवर्तन अपेक्षाकृत सरल हैं।