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

प्रदर्शन आश्चर्य और धारणाएँ :NOCOUNT ON करें

यदि आपने कभी प्रबंधन स्टूडियो का उपयोग किया है, तो यह आउटपुट संदेश शायद परिचित लगेगा:

(1 पंक्ति(पंक्ति) प्रभावित)

यह SQL सर्वर के DONE_IN_PROC . से आता है संदेश, जो किसी भी SQL कथन के सफलतापूर्वक पूरा होने पर भेजा जाता है जिसने परिणाम लौटाया है (एक निष्पादन योजना की पुनर्प्राप्ति सहित, यही कारण है कि जब आप वास्तव में केवल एक ही क्वेरी निष्पादित करते हैं तो आपको इनमें से दो संदेश दिखाई देते हैं)।

आप इन संदेशों को निम्न कमांड से दबा सकते हैं:

SET NOCOUNT ON;

तुम्हें ऐसा क्यों करना है? क्योंकि ये संदेश बातचीत हैं और अक्सर बेकार . मेरी बुरी आदतें और सर्वोत्तम अभ्यास प्रस्तुतियों में, मैं अक्सर SET NOCOUNT ON; जोड़ने की बात करता हूं सभी संग्रहीत प्रक्रियाओं के लिए, और तदर्थ प्रश्नों को सबमिट करने वाले एप्लिकेशन कोड में इसे चालू करना। (डिबगिंग के दौरान, हालांकि, हो सकता है कि आप संदेशों को वापस चालू करने के लिए फ़्लैग चाहते हों, क्योंकि उन मामलों में आउटपुट उपयोगी हो सकता है।)

मैंने हमेशा अस्वीकरण जोड़ा कि इस विकल्प को हर जगह चालू करने की सलाह सार्वभौमिक नहीं है; निर्भर करता है। पुराने स्कूल एडीओ रिकॉर्डसेट वास्तव में इन्हें परिणामसेट के रूप में व्याख्या करते हैं, इसलिए तथ्य के बाद उन्हें प्रश्नों में जोड़ना वास्तव में उन एप्लिकेशन को तोड़ सकता है जो पहले से ही उन्हें मैन्युअल रूप से छोड़ रहे हैं। और कुछ ओआरएम (खांसी NHibernate खांसी ) वास्तव में डीएमएल कमांड की सफलता निर्धारित करने के लिए परिणामों को पार्स करें (यूघ!) कृपया अपने परिवर्तनों का परीक्षण करें।

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

SET NOCOUNT OFF;
 
DECLARE @i INT = 1;
DECLARE @x TABLE(a INT);
INSERT @x(a) VALUES(1);
 
SELECT SYSDATETIME();
 
WHILE @i < 1000000
BEGIN
  UPDATE @x SET a = 1;
  SET @i += 1;
END
 
SELECT SYSDATETIME();

कुछ चीज़ें जो आप नोटिस कर सकते हैं:

  • संदेश फलक (1 row(s) affected) के उदाहरणों से भरा हुआ है संदेश:

  • आरंभिक SELECT SYSDATETIME(); पूरे बैच के पूरा होने तक खुद को परिणाम फलक में प्रस्तुत नहीं करता है। यह बाढ़ के कारण है।
  • इस बैच को चलने में लगभग 21 सेकंड का समय लगा।

अब, इसे DONE_IN_PROC के बिना दोहराते हैं संदेश, SET NOCOUNT OFF; . बदलकर करने के लिए SET NOCOUNT ON; और इसे फिर से चलाएँ।

जबकि संदेश फलक में अब प्रभावित पंक्ति (पंक्तियों) संदेशों की बाढ़ नहीं थी, बैच को चलने में अभी भी ~21 सेकंड का समय लगा।

फिर मैंने सोचा, एक सेकंड रुकिए, मुझे पता है कि क्या हो रहा है। मैं एक स्थानीय मशीन पर हूं, जिसमें कोई नेटवर्क शामिल नहीं है, साझा मेमोरी का उपयोग करते हुए, मेरे पास केवल एसएसडी और रैम के गॉब्स और गॉब्स हैं…

इसलिए मैंने दूरस्थ Azure SQL डेटाबेस - एक मानक, S0, V12 के विरुद्ध SSMS की अपनी स्थानीय प्रति का उपयोग करके परीक्षणों को दोहराया। इस बार, 1,000,000 से 100,000 तक पुनरावृत्तियों को कम करने के बाद भी, प्रश्नों में बहुत अधिक समय लगा। लेकिन फिर से प्रदर्शन में कोई ठोस अंतर नहीं था कि क्या DONE_IN_PROC संदेश भेजे जा रहे थे या नहीं। दोनों बैचों में लगभग 104 सेकंड लगे, और इसे कई पुनरावृत्तियों में दोहराया जा सकता था।

निष्कर्ष

वर्षों से, मैं इस धारणा के तहत काम कर रहा था कि SET NOCOUNT ON; किसी भी प्रदर्शन रणनीति का एक महत्वपूर्ण हिस्सा था। यह उन टिप्पणियों पर आधारित था, जो मैंने एक अलग युग में की थीं, और जो आज प्रकट होने की संभावना कम है।

उस ने कहा, मैं SET NOCOUNT ON . का उपयोग करना जारी रखूंगा , भले ही आज के हार्डवेयर पर प्रदर्शन में कोई उल्लेखनीय अंतर न हो। जहां भी संभव हो, मैं अभी भी नेटवर्क ट्रैफ़िक को कम करने के बारे में बहुत दृढ़ता से महसूस करता हूं। मुझे एक परीक्षण को लागू करने पर विचार करना चाहिए जहां मेरे पास बहुत अधिक विवश बैंडविड्थ है (शायद किसी के पास एओएल सीडी है जो वे मुझे उधार दे सकते हैं?), या एक मशीन है जहां प्रबंधन स्टूडियो की आउटपुट बफर सीमा से मेमोरी की मात्रा कम है, यह सुनिश्चित करने के लिए कि वहां सबसे खराब स्थिति में संभावित प्रभाव नहीं है। इस बीच, हालांकि यह आपके एप्लिकेशन के बारे में कथित प्रदर्शन को नहीं बदल सकता है, फिर भी यह आपके बटुए को हमेशा इस सेट विकल्प को चालू करने में मदद कर सकता है, विशेष रूप से Azure जैसी स्थितियों में - जहां आपसे निकासी ट्रैफ़िक के लिए शुल्क लिया जा सकता है।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. उन तालिका-मूल्यवान पैरामीटर्स को दृढ़ता से टाइप करें

  2. बिक्री रिकॉर्ड करने के लिए एक डेटाबेस मॉडलिंग। भाग 1

  3. ASPState में संभावित संवर्द्धन

  4. SQL में संबंध बनाएं

  5. Azure स्वचालन के तरीके