पिछली गर्मियों में, SQL सर्वर 2014 के लिए SP2 जारी होने के बाद, मैंने केवल एक क्वेरी प्रदर्शन समस्या की जांच करने से अधिक के लिए DBCC CLONEDATABASE का उपयोग करने के बारे में लिखा था। एक पाठक द्वारा पोस्ट पर हाल की एक टिप्पणी ने मुझे यह सोचने पर मजबूर कर दिया कि परीक्षण के लिए क्लोन डेटाबेस का उपयोग करने के तरीके के बारे में मेरे मन में जो कुछ था, उस पर मुझे विस्तार करना चाहिए। पीटर ने लिखा:
"मैं मुख्य रूप से एक सी # देव हूं और जब मैं उस एसक्यूएल सर्वर से आगे जाने की बात करता हूं तो मैं हर समय टी-एसक्यूएल के साथ लिखता हूं और सौदा करता हूं (काफी सभी डीबीए सामान, आंकड़े और इसी तरह) मैं वास्तव में बहुत कुछ नहीं जानता . वास्तव में यह भी नहीं पता कि मैं प्रदर्शन ट्यूनिंग के लिए इस तरह के क्लोन डीबी का उपयोग कैसे करूंगा"अच्छा पीटर, यहाँ तुम जाओ। मुझे आशा है कि यह मदद करता है!
सेटअप
DBCC CLONEDATABASE को SQL Server 2016 SP1 में उपलब्ध कराया गया था, इसलिए हम परीक्षण के लिए इसका उपयोग करेंगे क्योंकि यह वर्तमान रिलीज़ है, और क्योंकि मैं अपने डेटा को कैप्चर करने के लिए क्वेरी स्टोर का उपयोग कर सकता हूं। जीवन को आसान बनाने के लिए, मैं परीक्षण के लिए एक डेटाबेस बना रहा हूँ, न कि Microsoft से एक नमूना पुनर्स्थापित करने के लिए।
उपयोग [मास्टर];जाओ ड्रॉप डेटाबेस यदि मौजूद है [CustomerDB], [CustomerDB_CLONE]; GO /* उपयुक्त के रूप में फ़ाइल स्थान बदलें */ प्राथमिक पर डेटाबेस [CustomerDB] बनाएं ( NAME =N'CustomerDB', FILENAME =N' C:\Databases\CustomerDB.mdf', SIZE =512MB, MAXSIZE =असीमित, FILEGROWTH =65536KB) लॉग ऑन करें (NAME =N'CustomerDB_log', FILENAME =N'C:\Databases\CustomerDB_log.ldf' , SIZE =512MB MAXSIZE =असीमित , FILEGROWTH =65536KB ); GO ALTER DATABASE [CustomerDB] SET RECOVERY SIMPLE;
अब, एक टेबल बनाएं और कुछ डेटा जोड़ें:
उपयोग [ग्राहक डीबी]; टेबल बनाएं [डीबीओ]। [ग्राहक] ( [ग्राहक आईडी] [int] न्यूल नहीं, [फर्स्टनाम] [नवरचर] (64) न्यूल नहीं, [अंतिम नाम] [नवरचर] (64) नहीं न्यूल, [ईमेल] [नवरचर] (320) न्यूल नहीं, [सक्रिय] [बिट] नॉट डिफॉल्ट 1, [बनाया गया] [डेटाटाइम] नॉट डिफॉल्ट सिस्डेटटाइम (), [अपडेट किया गया] [डेटाटाइम] न्यूल, कॉन्स्ट्रेंट [पीके_कस्टमर] प्राथमिक कुंजी क्लस्टर ([ग्राहक आईडी]));जाओ /* यह तालिका में 1,000,000 पंक्तियां जोड़ता है; कम*/INSERT dbo जोड़ने के लिए स्वतंत्र महसूस करें। (TABLOCKX) वाले ग्राहक (CustomerID, FirstName, LastName, EMail, [Active]) RN =ROW_NUMBER() OVER (ऑर्डर बाय n), fn, ln, em, a FROM चुनें ( सेलेक्ट टॉप (1000000) fn, ln, em, a =MAX(a), n =MAX(NEWID ()) से (चुनें fn, ln, em, a, r =ROW_NUMBER() ओवर (उन्हें ऑर्डर के अनुसार पार्टिशन) ) FROM (सेलेक्ट टॉप (20000000) fn =LEFT(o.name, 64), ln =LEFT(c.name, 64), em =LEFT(o.name, LEN(c.name)%5+1) + '।' + बाएँ (c.name, LEN (o.name)% 5 + 2) + '@' + दाएँ (c. नाम, LEN (o. नाम + c. नाम)% 12 + 1) + बाएँ ( RTRIM(CHECKSUM(NEWID())),3) + '.com', a =मामला जब c.name '%y%' की तरह हो तो 0 ELSE 1 sys.all_objects से समाप्त हो जाता है जैसे कि sys.all_columns के रूप में सी ऑर्डर के रूप में शामिल हों NEWID () ) AS x) के रूप में y जहां r =1 समूह द्वारा fn, ln, उन्हें n द्वारा आदेश दिया गया है rn द्वारा z आदेश के रूप में; गैर-अनुक्रमित अनुक्रमणिका [फ़ोनबुक_ग्राहक] बनाएं [डीबीओ] पर जाएं। [ग्राहक] ([अंतिम नाम] ,[फर्स्टनाम])शामिल करें ([ईमेल]);
अब, हम क्वेरी स्टोर को सक्षम करेंगे:
उपयोग करें [मास्टर];डेटा में बदलाव करें [CustomerDB] SET QUERY_STORE =ON; परिवर्तन डेटाबेस [CustomerDB] सेट करेंएक बार जब हमारे पास डेटाबेस बन जाता है और आबाद हो जाता है, और हमने क्वेरी स्टोर को कॉन्फ़िगर कर दिया है, तो हम परीक्षण के लिए एक संग्रहीत कार्यविधि बनाएंगे:
उपयोग [CustomerDB]; GO DROP प्रक्रिया यदि मौजूद है [dbo]। [usp_GetCustomerInfo]; क्रिएट करें या प्रक्रिया बदलें [dbo]। फर्स्टनाम], [अंतिम नाम], [ईमेल], मामला जब [सक्रिय] =1 तब 'सक्रिय' अन्यथा 'निष्क्रिय' अंत [स्थिति] [डीबीओ] से। [ग्राहक] जहां [अंतिम नाम] =@ अंतिम नाम;ध्यान दें:मैंने शानदार नए CREATE OR ALTER PROCEDURE सिंटैक्स का उपयोग किया है जो SP1 में उपलब्ध है।
क्वेरी स्टोर में कुछ डेटा प्राप्त करने के लिए हम अपनी संग्रहीत प्रक्रिया को दो बार चलाएंगे। मैंने RECOMPILE के साथ जोड़ा है क्योंकि मुझे पता है कि ये दो इनपुट मान अलग-अलग योजनाएं बनाएंगे, और मैं उन दोनों को कैप्चर करना सुनिश्चित करना चाहता हूं।
EXEC [dbo].[usp_GetCustomerInfo] 'नाम' RECOMPILE के साथ;GOEXEC [dbo]।यदि हम क्वेरी स्टोर में देखते हैं, तो हम अपनी संग्रहीत प्रक्रिया से एक क्वेरी देखते हैं, और दो अलग-अलग योजनाएं (प्रत्येक की अपनी योजना_आईडी के साथ)। यदि यह एक उत्पादन वातावरण होता, तो हमारे पास रनटाइम आँकड़ों (अवधि, IO, CPU जानकारी) और अधिक निष्पादन के संदर्भ में काफी अधिक डेटा होता। भले ही हमारे डेमो में कम डेटा है, सिद्धांत वही है।
चुनें [क्यूएसक्यू]। [क्वेरी_आईडी], [क्यूएसपी]। [प्लान_आईडी], [क्यूएसक्यू]। [ऑब्जेक्ट_आईडी], [आरएस]। GETUTCDATE())), [qsp]। qsq] जॉइन करें [sys]। [query_store_query_text] [qst] ऑन [qsq]। [query_text_id] =[qst]। qsp]। [query_id] [sys] में शामिल हों। [query_store_runtime_stats] [rs] पर [qsp]। [plan_id] =[rs]। [plan_id] जहां [qsq]। [object_id] =OBJECT_ID (N'usp_GetCustomerInfo');क्वेरी संग्रहित प्रक्रिया क्वेरी से डेटा संग्रहीत करें क्वेरी संग्रहीत कार्यविधि निष्पादन के बाद डेटा संग्रहीत करें (query_id =1) दो अलग-अलग योजनाओं के साथ (plan_id =1, plan_id =2)
प्लान_आईडी =1 के लिए क्वेरी प्लान (इनपुट मान ='नाम') प्लान_आईडी =2 के लिए क्वेरी प्लान (इनपुट मान ='query_cost')एक बार हमारे पास क्वेरी स्टोर में आवश्यक जानकारी होने के बाद, हम डेटाबेस को क्लोन कर सकते हैं (क्वेरी स्टोर डेटा डिफ़ॉल्ट रूप से क्लोन में शामिल किया जाएगा):
DBCC CLONEDATABASE (N'CustomerDB', N'CustomerDB_CLONE');जैसा कि मैंने अपने पिछले CLONEDATABASE पोस्ट में उल्लेख किया है, क्लोन किए गए डेटाबेस को क्वेरी प्रदर्शन समस्याओं का परीक्षण करने के लिए उत्पाद समर्थन के लिए उपयोग करने के लिए डिज़ाइन किया गया है। जैसे, यह क्लोन होने के बाद ही पढ़ा जाता है। DBCC CLONEDATABASE को वर्तमान में क्या करने के लिए डिज़ाइन किया गया है, हम उससे आगे जाने जा रहे हैं, इसलिए फिर से, मैं आपको Microsoft दस्तावेज़ से यह नोट याद दिलाना चाहता हूँ:
DBCC CLONEDATABASE से उत्पन्न नया जनरेट किया गया डेटाबेस उत्पादन डेटाबेस के रूप में उपयोग करने के लिए समर्थित नहीं है और मुख्य रूप से समस्या निवारण और नैदानिक उद्देश्यों के लिए अभिप्रेत है।परीक्षण के लिए कोई भी परिवर्तन करने के लिए, मुझे डेटाबेस को केवल-पढ़ने के लिए मोड से बाहर निकालना होगा। और मैं इसके साथ ठीक हूं क्योंकि मैं इसे उत्पादन उद्देश्यों के लिए उपयोग करने की योजना नहीं बना रहा हूं। यदि यह क्लोन किया गया डेटाबेस उत्पादन वातावरण में है, तो मैं आपको इसका बैकअप लेने और इसे किसी देव या परीक्षण सर्वर पर पुनर्स्थापित करने और वहां अपना परीक्षण करने की सलाह देता हूं। मैं उत्पादन में परीक्षण की अनुशंसा नहीं करता, न ही मैं विरुद्ध . परीक्षण करने की अनुशंसा करता हूं उत्पादन उदाहरण (एक अलग डेटाबेस के साथ भी)।
/* इसे पढ़ने के लिए लिखें (इसका बैक अप लें और इसे कहीं और पुनर्स्थापित करें ताकि आप उत्पादन में काम नहीं कर रहे हों)*/ALTER DATABASE [CustomerDB_CLONE] NO_WAIT के साथ READ_WRITE सेट करें;अब जबकि मैं पढ़ने-लिखने की स्थिति में हूं, मैं बदलाव कर सकता हूं, कुछ परीक्षण कर सकता हूं और मीट्रिक कैप्चर कर सकता हूं। मैं यह सत्यापित करने के साथ शुरू करूंगा कि मुझे वही योजना मिलती है जो मैंने पहले की थी (अनुस्मारक, आपको यहां कोई आउटपुट नहीं दिखाई देगा क्योंकि क्लोन डेटाबेस में कोई डेटा नहीं है):
/* सत्यापित करें कि हमें वही प्लान */USE [CustomerDB_CLONE];GOEXEC [dbo].[usp_GetCustomerInfo] 'name';GOEXEC [dbo].[usp_GetCustomerInfo] 'query_cost' RECOMPILE के साथ मिल रहा है;क्वेरी स्टोर की जाँच करने पर, आपको पहले जैसा ही plan_id मान दिखाई देगा। query_id/plan_id संयोजन के लिए कई पंक्तियाँ हैं, क्योंकि अलग-अलग समय अंतराल के दौरान डेटा कैप्चर किया गया था (INTERVAL_LENGTH_MINUTES सेटिंग द्वारा निर्धारित, जिसे हम 5 पर सेट करते हैं)।
चुनें [क्यूएसक्यू]। [क्वेरी_आईडी], [क्यूएसपी]। [प्लान_आईडी], [क्यूएसक्यू]। [ऑब्जेक्ट_आईडी], [आरएस]। GETUTCDATE ())), [qsp]। [last_execution_time]) AS [LocalLastExecutionTime], [rsi]। [runtime_stats_interval_id], [rsi]। [start_time], [rsi]। [end_time], [qst]। [query_sql_text] , कनवर्टेडप्लान =TRY_CONVERT (XML, [qsp]। [query_plan]) [sys] से। [query_store_query] [qsq] जॉइन [sys]। [query_store_query_text] [qst] ऑन [qsq]। [query_text_id] [sys] में शामिल हों। [query_store_plan] [qsp] [qsq] पर। [rs]।;जाओक्लोन किए गए डेटाबेस के खिलाफ संग्रहित प्रक्रिया को निष्पादित करने के बाद क्वेरी स्टोर डेटा
परीक्षण कोड परिवर्तन
हमारे पहले परीक्षण के लिए, आइए देखें कि हम अपने कोड में बदलाव का परीक्षण कैसे कर सकते हैं - विशेष रूप से, हम चयन सूची से [सक्रिय] कॉलम को हटाने के लिए हमारी संग्रहीत प्रक्रिया को संशोधित करेंगे।
/* CREATE OR ALTER (क्वेरी से [एक्टिव] हटाएं)*/क्रिएट या ऑल्ट प्रोसेस [dbo] का उपयोग करके प्रक्रिया बदलें। ], [अंतिम नाम], [ईमेल] [डीबीओ] से। [ग्राहक] जहां [अंतिम नाम] =@ अंतिम नाम;संग्रहीत कार्यविधि को फिर से चलाएँ:
EXEC [dbo].[usp_GetCustomerInfo] 'नाम' RECOMPILE के साथ;GOEXEC [dbo]।यदि आप वास्तविक निष्पादन योजना प्रदर्शित करते हैं, तो आप देखेंगे कि दोनों प्रश्न अब एक ही योजना का उपयोग करते हैं, क्योंकि क्वेरी हमारे द्वारा मूल रूप से बनाए गए गैर-संकुल सूचकांक द्वारा कवर की जाती है।
निष्पादन योजना [सक्रिय] को हटाने के लिए संग्रहीत कार्यविधि को बदलने के बाद
हम क्वेरी स्टोर से सत्यापित कर सकते हैं, हमारी नई योजना में 41 का plan_id है:
चुनें [क्यूएसक्यू]। [क्वेरी_आईडी], [क्यूएसपी]। [प्लान_आईडी], [क्यूएसक्यू]। [ऑब्जेक्ट_आईडी], [आरएस]। GETUTCDATE ())), [qsp]। [last_execution_time]) AS [LocalLastExecutionTime], [rsi]। [runtime_stats_interval_id], [rsi]। [start_time], [rsi]। [end_time], [qst]। [query_sql_text] , कनवर्टेडप्लान =TRY_CONVERT (XML, [qsp]। [query_plan]) [sys] से। [query_store_query] [qsq] जॉइन [sys]। [query_store_query_text] [qst] ऑन [qsq]। [query_text_id] [sys] में शामिल हों। [query_store_plan] [qsp] [qsq] पर। [rs]।;संग्रहीत प्रक्रिया बदलने के बाद क्वेरी स्टोर डेटा
आप यहां यह भी देखेंगे कि एक नया query_id (40) है। क्वेरी स्टोर टेक्स्ट मिलान करता है, और हमने क्वेरी का टेक्स्ट बदल दिया है, इस प्रकार एक नया query_id उत्पन्न होता है। यह भी ध्यान रखें कि object_id वही रहा, क्योंकि उपयोग में CREATE OR ALTER सिंटैक्स का उपयोग किया गया था। आइए एक और बदलाव करें, लेकिन DROP का उपयोग करें और फिर CREATE OR ALTER का उपयोग करें।
/* DROP का उपयोग करके प्रक्रिया बदलें और फिर बनाएं या बदलें (सम्मिलित करें [FirstName] और [LastName])*/DROP प्रक्रिया यदि मौजूद है [dbo]।[usp_GetCustomerInfo]; क्रिएट करें या प्रक्रिया बदलें [dbo]। (@LastName [nvarchar](64)) AS SELECT [CustomerID], RTRIM([FirstName]) + '' + RTRIM([LastName]), [ईमेल] फ्रॉम [डीबीओ]। [ग्राहक] जहां [अंतिम नाम] =@ अंतिम नाम;अब, हम प्रक्रिया को फिर से चलाते हैं:
EXEC [dbo].[usp_GetCustomerInfo] 'name';GOEXEC [dbo].[usp_GetCustomerInfo] 'query_cost' RECOMPILE के साथ;अब क्वेरी स्टोर से आउटपुट अधिक दिलचस्प हो जाता है, और ध्यान दें कि मेरा क्वेरी स्टोर विधेय WHERE [qsq] में बदल गया है। [object_id] <> 0.
चुनें [क्यूएसक्यू]। [क्वेरी_आईडी], [क्यूएसपी]। [प्लान_आईडी], [क्यूएसक्यू]। [ऑब्जेक्ट_आईडी], [आरएस]। GETUTCDATE ())), [qsp]। [last_execution_time]) AS [LocalLastExecutionTime], [rsi]। [runtime_stats_interval_id], [rsi]। [start_time], [rsi]। [end_time], [qst]। [query_sql_text] , कनवर्टेडप्लान =TRY_CONVERT (XML, [qsp]। [query_plan]) [sys] से। [query_store_query] [qsq] जॉइन [sys]। [query_store_query_text] [qst] ऑन [qsq]। [query_text_id] [sys] में शामिल हों। [query_store_plan] [qsp] [qsq] पर। [rs]। [plan_id] [sys] में शामिल हों। [query_store_runtime_stats_interval] [rsi] ऑन [rs]।DROP का उपयोग करके संग्रहित प्रक्रिया को बदलने के बाद क्वेरी स्टोर डेटा और फिर बनाएं या बदलेंउन्हें>
Object_id बदल कर 661577395 हो गया है, और मेरे पास एक नया query_id (42) है क्योंकि क्वेरी टेक्स्ट बदल गया है, और एक नया plan_id (43)। हालांकि यह योजना अभी भी मेरे गैर-संकुल सूचकांक की एक अनुक्रमणिका खोज है, फिर भी यह क्वेरी स्टोर में एक अलग योजना है। समझें कि जब आप क्वेरी स्टोर का उपयोग कर रहे हों तो ऑब्जेक्ट बदलने के लिए अनुशंसित विधि ड्रॉप और क्रिएट पैटर्न के बजाय ALTER का उपयोग करना है। यह उत्पादन में सच है, और इस तरह के परीक्षण के लिए, जैसा कि आप परिवर्तन को आसान बनाने के लिए ऑब्जेक्ट_आईडी को समान रखना चाहते हैं।
परीक्षण अनुक्रमणिका परिवर्तन
हमारे परीक्षण के भाग II के लिए, क्वेरी को बदलने के बजाय, हम यह देखना चाहते हैं कि क्या हम सूचकांक को बदलकर प्रदर्शन में सुधार कर सकते हैं। इसलिए हम संग्रहीत कार्यविधि को वापस मूल क्वेरी में बदल देंगे, फिर अनुक्रमणिका को संशोधित करेंगे।
बनाएं या प्रक्रिया बदलें [डीबीओ]। 'सक्रिय' ELSE 'निष्क्रिय' अंत [स्थिति] [dbo] से। [ग्राहक] जहां [LastName] =@LastName; GO /* क्वेरी को कवर करने के लिए [सक्रिय] जोड़ने के लिए मौजूदा अनुक्रमणिका को संशोधित करें*/गैर-अनुक्रमित अनुक्रमणिका बनाएं [PhoneBook_Customers] चालू [डीबीओ]।क्योंकि मैंने मूल संग्रहीत कार्यविधि को छोड़ दिया है, मूल योजना अब कैश में नहीं है। अगर मैंने परीक्षण के हिस्से के रूप में पहले इस सूचकांक को बदल दिया था, तो याद रखें कि जब तक मैं पुनर्संकलन को मजबूर नहीं करता तब तक क्वेरी स्वचालित रूप से नई अनुक्रमणिका का उपयोग नहीं करेगी। मैं ऑब्जेक्ट पर sp_recompile का उपयोग कर सकता था, या मैं प्रक्रिया पर RECOMPILE विकल्प के साथ उपयोग करना जारी रख सकता था यह देखने के लिए कि मुझे दो अलग-अलग मूल्यों के साथ एक ही योजना मिली है (याद रखें कि मेरे पास शुरुआत में दो अलग-अलग योजनाएं थीं)। मुझे RECOMPILE की आवश्यकता नहीं है क्योंकि योजना कैश में नहीं है, लेकिन मैं इसे निरंतरता के लिए छोड़ रहा हूँ।
EXEC [dbo].[usp_GetCustomerInfo] 'नाम' RECOMPILE के साथ;GOEXEC [dbo]।क्वेरी स्टोर के भीतर मुझे एक और नया query_id दिखाई देता है (क्योंकि object_id मूल रूप से उससे भिन्न है!) और एक नया plan_id:
नई अनुक्रमणिका जोड़ने के बाद क्वेरी स्टोर डेटा
यदि मैं योजना की जाँच करता हूँ, तो मैं देख सकता हूँ कि संशोधित अनुक्रमणिका का उपयोग किया जा रहा है।
इंडेक्स में [एक्टिव] जोड़े जाने के बाद क्वेरी प्लान (प्लान_आईडी =50)उन्हें>
और अब जब मेरे पास एक अलग योजना है, तो मैं इसे एक कदम आगे ले जा सकता हूं और यह सत्यापित करने के लिए उत्पादन कार्यभार को अनुकरण करने का प्रयास कर सकता हूं कि विभिन्न इनपुट पैरामीटर के साथ, यह संग्रहीत प्रक्रिया एक ही योजना उत्पन्न करती है और नई अनुक्रमणिका का उपयोग करती है। हालाँकि, यहाँ एक चेतावनी है। आपने इंडेक्स सीक ऑपरेटर पर चेतावनी देखी होगी - ऐसा इसलिए होता है क्योंकि [लास्टनाम] कॉलम पर कोई आंकड़े नहीं होते हैं। जब हमने एक सम्मिलित कॉलम के रूप में [सक्रिय] के साथ सूचकांक बनाया, तो आंकड़ों को अद्यतन करने के लिए तालिका को पढ़ा गया। तालिका में कोई डेटा नहीं है, इसलिए आंकड़ों की कमी है। यह निश्चित रूप से इंडेक्स टेस्टिंग को ध्यान में रखने वाली बात है। जब आंकड़े गायब होते हैं, तो अनुकूलक अनुमान का उपयोग करेगा जो अनुकूलक को उस योजना का उपयोग करने के लिए मना सकता है या नहीं, जिसकी आप अपेक्षा कर रहे हैं।
सारांश
मैं DBCC CLONEDATABASE का बहुत बड़ा प्रशंसक हूं। मैं क्वेरी स्टोर का और भी बड़ा प्रशंसक हूं। जब आप उन दोनों को एक साथ रखते हैं, तो आपके पास अनुक्रमणिका और कोड परिवर्तनों के त्वरित परीक्षण के लिए बड़ी क्षमता होती है। इस पद्धति के साथ, आप मुख्य रूप से सुधारों को मान्य करने के लिए निष्पादन योजनाओं को देख रहे हैं। चूंकि क्लोन किए गए डेटाबेस में कोई डेटा नहीं है, इसलिए आप निष्पादन योजना में कथित लाभ को साबित या अस्वीकृत करने के लिए संसाधन उपयोग और रनटाइम आँकड़ों को कैप्चर नहीं कर सकते। आपको अभी भी डेटाबेस को पुनर्स्थापित करने और डेटा के एक पूर्ण सेट के खिलाफ परीक्षण करने की आवश्यकता है - और क्वेरी स्टोर अभी भी मात्रात्मक डेटा को कैप्चर करने में एक बड़ी मदद हो सकती है। हालांकि, उन मामलों के लिए जहां योजना सत्यापन पर्याप्त है, या आप में से जो वर्तमान में कोई परीक्षण नहीं करते हैं, उनके लिए DBCC CLONEDATABASE वह आसान बटन प्रदान करता है जिसकी आपको तलाश थी। क्वेरी स्टोर प्रक्रिया को और भी आसान बना देता है।
ध्यान देने योग्य कुछ बातें:
संग्रहीत प्रक्रियाओं को कॉल करते समय मैं RECOMPILE के साथ उपयोग करने की अनुशंसा नहीं करता (या उन्हें इस तरह घोषित करता हूं - पॉल व्हाइट की पोस्ट देखें)। मैंने इस डेमो के लिए इस विकल्प का उपयोग किया क्योंकि मैंने एक पैरामीटर-संवेदी संग्रहीत कार्यविधि बनाई थी, और मैं यह सुनिश्चित करना चाहता था कि अलग-अलग मान अलग-अलग योजनाएँ उत्पन्न करते हैं और कैशे से किसी योजना का उपयोग नहीं करते हैं।
SQL सर्वर 2014 SP2 में DBCC CLONEDATABASE के साथ इन परीक्षणों को चलाना काफी संभव है, लेकिन स्पष्ट रूप से प्रश्नों और मेट्रिक्स को कैप्चर करने के साथ-साथ प्रदर्शन को देखने के लिए एक अलग दृष्टिकोण है। यदि आप क्वेरी स्टोर के बिना इसी परीक्षण पद्धति को देखना चाहते हैं, तो एक टिप्पणी छोड़ें और मुझे बताएं!