Database
 sql >> डेटाबेस >  >> RDS >> Database

सांख्यिकी के स्वचालित अपडेट क्वेरी प्रदर्शन को कैसे प्रभावित कर सकते हैं

अपनी पिछली पोस्ट में, मैंने यह निर्धारित करने के लिए कि क्या वे क्वेरी प्रदर्शन को प्रभावित कर रहे थे, आंकड़ों के स्वचालित अपडेट को ट्रैक करने के लिए विभिन्न तरीकों की खोज की। पोस्ट के उत्तरार्ध में मैंने विकल्प शामिल किए, जिनमें से एक ऑटो अपडेट स्टैटिस्टिक्स एसिंक्रोनसली डेटाबेस सेटिंग को सक्षम करना था। इस पोस्ट में, मैं देखना चाहता हूं कि क्वेरी निष्पादन से पहले स्वचालित अपडेट होने पर क्वेरी प्रदर्शन कैसे बदलता है, और यदि अपडेट एसिंक्रोनस है तो प्रदर्शन का क्या होता है।

सेट अप

मैंने एडवेंचरवर्क्स2012 डेटाबेस की एक प्रति के साथ शुरुआत की, और फिर इस स्क्रिप्ट का उपयोग करके 200 मिलियन से अधिक पंक्तियों के साथ SalesOrderHeader तालिका की एक प्रति बनाई। तालिका में SalesOrderID पर एक संकुल अनुक्रमणिका है, और CustomerID, OrderDate, SubTotal पर एक गैर-संकुल अनुक्रमणिका है। [नोट:यदि आप बार-बार परीक्षण करने जा रहे हैं, तो इस समय अपने आप को कुछ समय बचाने के लिए इस डेटाबेस का बैकअप लें]। डेटा लोड करने और गैर-क्लस्टर इंडेक्स बनाने के बाद, मैंने पंक्ति गणना सत्यापित की और गणना की कि स्वचालित अपडेट को लागू करने के लिए कितनी पंक्तियों (लगभग) को संशोधित करने की आवश्यकता होगी।

SELECTOBJECT_NAME([p].[object_id]) [TableName],[si].[name] [IndexName],[au].[type_desc] [Type],[p].[rows] [RowCount], ([p].[rows]*.20) + 500 [अपडेट थ्रेशोल्ड],[au].total_pages [PageCount],(([au].[total_pages]*8)/1024)/1024 [TotalGB]FROM [sys ]। [विभाजन] [पी] [एसआईएस] में शामिल हों। [आवंटन_यूनिट्स] [एयू] पर [पी]। [पार्टिशन_आईडी] =[एयू]। [कंटेनर_आईडी] [एसआईएस] में शामिल हों। [इंडेक्स] [सी] [पी] पर .[object_id] =[si].object_id और [p].[index_id] =[si].[index_id]जहां [p].[object_id] =OBJECT_ID(N'Sales.Big_SalesOrderHeader');


Big_SalesOrderHeader CIX और NCI जानकारी

मैंने अनुक्रमणिका के लिए वर्तमान सांख्यिकी शीर्षलेख को भी सत्यापित किया है:

DBCC SHOW_STATISTICS ('Sales.Big_SalesOrderHeader',[IX_Big_SalesOrderHeader_CustomerID_OrderDate_SubTotal]);


NCI सांख्यिकी:प्रारंभ में

मैंने तब संग्रहीत प्रक्रिया बनाई जिसे मैं परीक्षण के लिए उपयोग करूंगा। यह एक सीधी प्रक्रिया है जो Sales.Big_SalesOrderHeader से पूछताछ करती है, और विश्लेषण के लिए CustomerID और OrderDate द्वारा बिक्री डेटा एकत्र करती है:

CREATE PROCEDURE Sales.usp_GetCustomerStats@CustomerID INT,@StartDate DATETIME,@EndDate DATETIMEASBEGIN SET NOCOUNT ON; ग्राहक आईडी, DATEPART (वर्ष, ऑर्डर दिनांक), DATEPART (महीना, ऑर्डर दिनांक), COUNT ([SalesOrderID]) [बिक्री] से परिकलित के रूप में चुनें। DATEPART(YEAR, OrderDate), DATEPART (MONTH, OrderDate) DATEPART (YEAR, OrderDate), DATEPART (MONTH, OrderDate) द्वारा ऑर्डर करें;END

अंत में, संग्रहीत कार्यविधि को निष्पादित करने से पहले, मैंने एक विस्तारित ईवेंट सत्र बनाया ताकि मैं sp_statement_starting और sp_statement_completed का उपयोग करके क्वेरी अवधि को ट्रैक कर सकूं। मैंने auto_stats ईवेंट भी जोड़ा, क्योंकि भले ही मुझे अपडेट होने की उम्मीद नहीं थी, मैं बाद में इसी सत्र परिभाषा का उपयोग करना चाहता था।

ईवेंट सत्र बनाएं [StatsUpdate_QueryPerf] सर्वर पर ईवेंट sqlserver.auto_stats, ईवेंट जोड़ें StatsUpdate_QueryPerf.xel')के साथ (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB, MEMORY_PARTITION_MODE=NOONE); 

परीक्षा

मैंने विस्तारित ईवेंट सत्र शुरू किया, और फिर विभिन्न CustomerIDs का उपयोग करके संग्रहीत कार्यविधि को कई बार निष्पादित किया:

ईवेंट सत्र बदलें [StatsUpdate_QueryPerf]SERVERSTATE =START;GO EXEC Sales.usp_GetCustomerStats 11331, '2012-08-01 00:00:00.000', '2012-08-31 23:59:59.997'GOEXEC Sales.usp_GetCustomerStats 11330, '2013-01-01 00:00:00.000', '2013-01-31 23:59:59.997'GOEXEC Sales.usp_GetCustomerStats 11506, '2012-11-01 00:00:00.000', '2012-11 -30 23:59:59.997'GOEXEC Sales.usp_GetCustomerStats 17061, '2013-01-01 00:00:00.000', '2013-01-31 23:59:59.97'GOEXEC Sales.usp_GetCustomerStats 11711, '2013-03- 01 00:00:00.000', '2013-03-31 23:59:59.997'GOEXEC Sales.usp_GetCustomerStats 15131, '2013-02-01 00:00:00.000', '2013-02-28 23:59:59.997 'GOEXEC Sales.usp_GetCustomerStats 29837, '2012-10-01 00:00:00.000', '2012-10-31 23:59:59.997'GOEXEC Sales.usp_GetCustomerStats 15750, '2013-03-01 00:00:00.000' , '2013-03-31 23:59:59.97'जाओ

मैंने प्रक्रिया कैश को क्वेरी करके निष्पादन संख्या और योजना को सत्यापित किया:

SELECTOBJECT_NAME([st].[objectid]),[st].[text],[qs].[execution_count],[qs].[creation_time],[qs].[last_execution_time],[qs]. [मिन_वर्कर_टाइम], [क्यूएस]। ]से [sys]। जहां [सेंट]। [पाठ] '% usp_GetCustomerStats%' और OBJECT_NAME ([सेंट]। [ऑब्जेक्टिड]) को पसंद नहीं है;


योजना कैश:प्रारंभ में


एसक्यूएल संतरी योजना एक्सप्लोरर का उपयोग करते हुए संग्रहित प्रक्रिया के लिए क्वेरी योजना

मैं देख सकता था कि योजना 2014-04-08 18:59:39.850 पर बनाई गई थी। कैश में योजना के साथ, मैंने विस्तारित ईवेंट सत्र रोक दिया:

ईवेंट सत्र बदलें [StatsUpdate_QueryPerf]SERVERSTATE =STOP;

इसके बाद मैंने इस स्क्रिप्ट का उपयोग करके तालिका में डेटा की लगभग 47 मिलियन पंक्तियों को जोड़ा, जो वर्तमान आँकड़ों को अमान्य करने के लिए आवश्यक सीमा से अधिक है। डेटा जोड़ने के बाद, मैंने तालिका में पंक्तियों की संख्या सत्यापित की:


Big_SalesOrderHeader CI:डेटा लोड होने के बाद

इससे पहले कि मैं अपनी संग्रहीत प्रक्रिया को फिर से चलाता, मैंने यह सुनिश्चित करने के लिए योजना कैश की जाँच की कि कुछ भी नहीं बदला है, और सत्यापित किया कि आँकड़े अभी तक अपडेट नहीं हुए हैं। याद रखें, भले ही इस बिंदु पर आंकड़े अमान्य कर दिए गए हों, वे तब तक अपडेट नहीं होंगे जब तक कि आंकड़ों का उपयोग करने वाली क्वेरी निष्पादित नहीं हो जाती (संदर्भ के लिए:यह समझना कि सांख्यिकी कब स्वचालित रूप से अपडेट होगी)। अंतिम चरण के लिए, मैंने विस्तारित ईवेंट सत्र फिर से शुरू किया, और फिर संग्रहीत कार्यविधि को कई बार चलाया। उन निष्पादनों के बाद, मैंने फिर से योजना कैश की जाँच की:


योजना कैश:डेटा लोड के बाद

एक्जीक्यूशन_काउंट फिर से 8 है, और अगर हम प्लान के create_time को देखें, तो हम देख सकते हैं कि यह 2014-04-08 19:32:52.913 में बदल गया है। यदि हम योजना की जाँच करते हैं, तो हम देख सकते हैं कि यह वही है, भले ही योजना को फिर से संकलित किया गया हो:


एसक्यूएल संतरी योजना एक्सप्लोरर का उपयोग करते हुए संग्रहित प्रक्रिया के लिए क्वेरी योजना

विस्तारित ईवेंट आउटपुट का विश्लेषण

मैंने पहली विस्तारित ईवेंट फ़ाइल ली - डेटा लोड होने से पहले - और इसे एसएसएमएस में खोला, फिर एक फ़िल्टर लागू किया ताकि संग्रहीत प्रक्रिया से केवल कथन सूचीबद्ध हों:


विस्तारित ईवेंट आउटपुट:प्रारंभिक SP निष्पादन के बाद

आप देख सकते हैं कि संग्रहीत कार्यविधि के आठ (8) निष्पादन हैं, जिसमें क्वेरी अवधि थोड़ी भिन्न होती है।

मैंने दूसरी विस्तारित इवेंट फ़ाइल ली - डेटा लोड होने के बाद - इसे एसएसएमएस खोला, और फिर से फ़िल्टर किया ताकि संग्रहीत प्रक्रिया से केवल बयान, साथ ही auto_stats ईवेंट सूचीबद्ध हों:


विस्तारित ईवेंट आउटपुट:डेटा लोड होने के बाद SP निष्पादन

आउटपुट छोटा कर दिया गया है, क्योंकि मुख्य परिणाम दिखाने के लिए इसकी आवश्यकता नहीं है। नीली हाइलाइट की गई प्रविष्टियां संग्रहित प्रक्रिया के पहले निष्पादन का प्रतिनिधित्व करती हैं, और ध्यान दें कि कई चरण हैं - आंकड़ों का अद्यतन निष्पादन का हिस्सा है। SELECT स्टेटमेंट शुरू होता है (attach_activity_id.seq =3), और आंकड़ों के अपडेट तब निष्पादित होते हैं। हमारे उदाहरण में, हमारे पास वास्तव में तीन आंकड़ों के अपडेट हैं। एक बार जब अंतिम अद्यतन पूरा हो जाता है (attach_activity_id.seq =11), तो संग्रहीत प्रक्रिया शुरू होती है और पूरी होती है (attach_activity_id.seq =13 और संलग्न_एक्टिविटी_आईडी.seq =14)। दिलचस्प रूप से पर्याप्त है, संग्रहीत कार्यविधि के लिए एक दूसरा sp_statement_starting ईवेंट है (संभवतः पहले वाले को अनदेखा कर दिया गया है), इसलिए संग्रहीत कार्यविधि के लिए कुल अवधि की गणना बिना की जाती है आँकड़ों का अद्यतन।

इस परिदृश्य में, आंकड़े होने पर स्वचालित रूप से तुरंत अपडेट हो जाता है - यानी, जब एक क्वेरी जो अमान्य आंकड़ों का उपयोग करती है - क्वेरी को लंबे समय तक चलने का कारण बनती है, भले ही sp_statement_completed ईवेंट पर आधारित क्वेरी अवधि अभी भी 14000 से कम हो। अंतिम परिणाम यह है कि वहां प्रदर्शन को क्वेरी करने का कोई लाभ नहीं है, क्योंकि आंकड़े अपडेट से पहले और बाद में योजना बिल्कुल समान है। इस परिदृश्य में, तालिका में अधिक डेटा जोड़े जाने के बाद क्वेरी योजना और निष्पादन अवधि परिवर्तित नहीं होती है, इसलिए आंकड़ों का अद्यतन केवल इसके प्रदर्शन में बाधा डालता है। अब देखते हैं कि जब हम ऑटो अपडेट स्टैटिस्टिक्स एसिंक्रोनसली विकल्प को सक्षम करते हैं तो क्या होता है।

परीक्षा, संस्करण 2

हम उस बैकअप को बहाल करके शुरू करते हैं जो मैंने पहला परीक्षण शुरू करने से पहले लिया था। मैंने संग्रहीत कार्यविधि को फिर से बनाया और फिर आंकड़ों को अतुल्यकालिक रूप से अद्यतन करने के लिए डेटाबेस विकल्प को बदल दिया:

उपयोग [मास्टर];GOALTER DATABASE [AdventureWorks2012_Big] NO_WAITGO के साथ AUTO_UPDATE_STATISTICS_ASYNC सेट करें

मैंने विस्तारित ईवेंट सत्र शुरू किया, और अलग-अलग CustomerIDs का उपयोग करके कई बार संग्रहीत कार्यविधि को फिर से निष्पादित किया:

ईवेंट सत्र बदलें [StatsUpdate_QueryPerf]SERVERSTATE =START;GO EXEC Sales.usp_GetCustomerStats11331, '2012-08-01 00:00:00.000', '2012-08-31 23:59:59.997'GOEXEC Sales.usp_GetCustomerStats11330, '2013-01-01 00:00:00.000', '2013-01-31 23:59:59.97'GOEXEC Sales.usp_GetCustomerStats11506, '2012-11-01 00:00:00.000', '2012-11-30 23 :59:59.97'GOEXEC Sales.usp_GetCustomerStats17061, '2013-01-01 00:00:00.000', '2013-01-31 23:59:59.997'GOEXEC Sales.usp_GetCustomerStats11711, '2013-03-01 00:00:00.000', '2013-03-31 23:59:59.997'GOEXEC Sales.usp_GetCustomerStats15131, '2013-02-01 00:00:00.000', '2013-02-28 23:59:59.997'GOEXEC Sales.usp_GetCustomerStats29837, '2012-10-01 00:00:00.000', '2012-10-31 23:59:59.97'GOEXEC Sales.usp_GetCustomerStats15750, '2013-03-01 00:00:00.000', '2013-03-31 23 :59:59.97'GO

मैंने प्रक्रिया कैश को क्वेरी करके निष्पादन संख्या और योजना को सत्यापित किया:


प्लान कैश:एट स्टार्ट, टेस्ट 2


एसक्यूएल संतरी योजना एक्सप्लोरर का उपयोग करते हुए संग्रहित प्रक्रिया के लिए क्वेरी योजना

इस परीक्षण के लिए, 2014-04-08 21:15:55.490 पर योजना बनाई गई थी। मैंने पहले की तरह ही क्वेरी का उपयोग करते हुए, विस्तारित ईवेंट सत्र को रोक दिया और तालिका में डेटा की लगभग 47 मिलियन पंक्तियों को फिर से जोड़ा।

एक बार डेटा जोड़े जाने के बाद, मैंने यह सुनिश्चित करने के लिए योजना कैश की जाँच की कि कुछ भी नहीं बदला है, और सत्यापित किया कि आँकड़े अभी तक अपडेट नहीं हुए हैं। अंत में, मैंने विस्तारित ईवेंट सत्र फिर से शुरू किया, और फिर संग्रहीत कार्यविधि को आठ बार और चलाया। योजना कैश में एक अंतिम झलक ने 16 पर एक्ज़ीक्यूटिव_काउंट और 2014-04-08 21:15:55.490 का create_time दिखाया। एक्ज़ीक्यूशन_काउंट और क्रिएट_टाइम दर्शाता है कि आंकड़े अपडेट नहीं हुए हैं, क्योंकि प्लान को अभी तक कैश से फ्लश नहीं किया गया है (यदि ऐसा होता, तो हमारे पास बाद में create_time और एक एक्ज़ीक्यूटिव_काउंट 8 होता)।


प्लान कैश:डेटा लोड होने के बाद, टेस्ट 2

यदि हम SSMS में डेटा लोड होने के बाद से विस्तारित ईवेंट आउटपुट खोलते हैं, और फिर से फ़िल्टर करते हैं, तो हम केवल संग्रहीत कार्यविधि, साथ ही auto_stats ईवेंट से स्टेटमेंट देखते हैं, हम इसे पाते हैं (ध्यान दें कि आउटपुट दो स्क्रीन शॉट्स में टूटा हुआ है):


विस्तारित ईवेंट आउटपुट:टेस्ट 2, डेटा लोड होने के बाद SP निष्पादन, भाग I


विस्तारित ईवेंट आउटपुट:टेस्ट 2, डेटा लोड होने के बाद SP निष्पादन, भाग II

संग्रहीत कार्यविधि की पहली कॉल के निष्पादन के लिए ईवेंट नीले रंग में हाइलाइट किए गए हैं - वे 2014-04-08 21:54:14.9480607 से शुरू होते हैं और सात (7) ईवेंट होते हैं। ध्यान दें कि तीन (3) auto_stats ईवेंट होते हैं, लेकिन उनमें से कोई भी वास्तव में पूर्ण नहीं होता है, जैसा कि हमने देखा था जब सांख्यिकी एसिंक्रोनस रूप से ऑटो अपडेट विकल्प अक्षम किया गया था। आप देखेंगे कि किसी एक आंकड़े के लिए स्वचालित अपडेट लगभग तुरंत शुरू हो जाता है (2014-04-08 21:54:14.9481288), और इसके तीन ईवेंट के आगे लाल टेक्स्ट 'स्टेट अपडेट #1' है। वह सांख्यिकी अद्यतन 2014-04-08 21:54:16.5392219 पर समाप्त होता है, इसके शुरू होने के दो सेकंड के भीतर, लेकिन प्रक्रिया के अन्य सभी निष्पादन पूर्ण होने के बाद। यही कारण है कि sys.dm_exec_query_stats से निष्पादन_काउंट 16 दिखाता है। XE आउटपुट से, हम देख सकते हैं कि अन्य आँकड़े अपडेट तब पूर्ण होते हैं (स्टेट अपडेट #2 और स्टेट अपडेट #3)। सभी अद्यतन प्रारंभिक संग्रहीत कार्यविधि के निष्पादन के लिए अतुल्यकालिक हैं।

सारांश

जैसा कि आप देख सकते हैं, आंकड़ों के स्वचालित अपडेट में क्वेरी प्रदर्शन को नकारात्मक रूप से प्रभावित करने की क्षमता होती है। प्रभाव की मात्रा उस डेटा की मात्रा पर निर्भर करेगी जिसे आंकड़ों और सिस्टम संसाधनों को अद्यतन करने के लिए पढ़ा जाना है। कुछ मामलों में, क्वेरी के प्रदर्शन में केवल मिलीसेकंड की वृद्धि होती है और यह उपयोगकर्ताओं के लिए सबसे अधिक अगोचर है। दूसरी बार, अवधि नाटकीय रूप से बढ़ सकती है, जो तब अंतिम-उपयोगकर्ता अनुभव को प्रभावित करती है। ऐसे मामले में जहां आंकड़ों के अपडेट के बाद क्वेरी प्लान नहीं बदलता है, क्वेरी प्रदर्शन पर प्रभाव को कम करने के लिए ऑटो अपडेट स्टैटिस्टिक्स एसिंक्रोनसली विकल्प को सक्षम करने पर विचार करना उचित है।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. isql . में कमांड इतिहास

  2. एक संदेश प्रणाली के लिए डेटाबेस मॉडल

  3. टी-एसक्यूएल में तिथि के अनुसार ऑर्डर कैसे करें

  4. SQL में तालिका का नाम कैसे बदलें

  5. एक पुस्तकालय डेटा मॉडल

© कॉपीराइट http://hi.sqldat.com सर्वाधिकार सुरक्षित