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

एक तदर्थ कार्यभार के प्रदर्शन प्रभाव की जांच

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

SELECT objtype AS [CacheType],
  COUNT_BIG(*) AS [Total Plans],
  SUM(CAST(size_in_bytes AS DECIMAL(18, 2))) / 1024 / 1024 AS [Total MBs],
  AVG(usecounts) AS [Avg Use Count],
  SUM(CAST((CASE WHEN usecounts = 1 THEN size_in_bytes
    ELSE 0
    END) AS DECIMAL(18, 2))) / 1024 / 1024 AS [Total MBs – USE Count 1],
  SUM(CASE WHEN usecounts = 1 THEN 1
    ELSE 0
    END) AS [Total Plans – USE Count 1]
FROM sys.dm_exec_cached_plans
GROUP BY objtype
ORDER BY [Total MBs – USE Count 1] DESC;

अगर मैं इस क्वेरी को उत्पादन परिवेश के विरुद्ध चलाता हूं, तो हमें निम्न जैसा आउटपुट मिल सकता है:

इस स्क्रीनशॉट से आप देख सकते हैं कि हमारे पास प्लान कैश के लिए कुल लगभग 3GB है, और उसमें से 1.7GB 158,000 से अधिक एडहॉक प्रश्नों की योजना के लिए है। उस 1.7GB में से, लगभग 500MB का उपयोग 125,000 योजनाओं के लिए किया जाता है जो ONE . को निष्पादित करते हैं केवल समय। लगभग 1GB प्लान कैश तैयार और प्रक्रिया योजनाओं के लिए है, और वे केवल लगभग 300MB मूल्य का स्थान लेते हैं। लेकिन औसत उपयोग गणना पर ध्यान दें - प्रक्रियाओं के लिए 1 मिलियन से अधिक। इस आउटपुट को देखते हुए, मैं इस कार्यभार को मिश्रित के रूप में वर्गीकृत करूंगा - कुछ पैरामीटरयुक्त प्रश्न, कुछ तदर्थ।

किम्बर्ली का ब्लॉग पोस्ट ढेर सारे एडहॉक प्रश्नों से भरे प्लान कैश के प्रबंधन के विकल्पों पर चर्चा करता है। जब आपके पास एडहॉक वर्कलोड होता है तो प्लान कैश ब्लोट सिर्फ एक समस्या है, और इस पोस्ट में मैं उन सभी संकलनों के परिणामस्वरूप सीपीयू पर पड़ने वाले प्रभाव का पता लगाना चाहता हूं। जब SQL सर्वर में कोई क्वेरी निष्पादित होती है, तो यह संकलन और अनुकूलन के माध्यम से जाती है, और इस प्रक्रिया से जुड़ा ओवरहेड होता है, जो अक्सर CPU लागत के रूप में प्रकट होता है। एक बार क्वेरी प्लान कैश में होने के बाद, इसका पुन:उपयोग किया जा सकता है। पैरामीटरयुक्त क्वेरीज़ पहले से कैश में मौजूद योजना का पुन:उपयोग कर सकती हैं, क्योंकि क्वेरी टेक्स्ट बिल्कुल समान है। जब कोई तदर्थ क्वेरी निष्पादित होती है तो वह कैश में योजना का केवल पुन:उपयोग करेगी यदि उसके पास सटीक है समान टेक्स्ट और इनपुट मान .

सेटअप

हमारे परीक्षण के लिए हम टीएसक्यूएल में एक यादृच्छिक स्ट्रिंग उत्पन्न करेंगे और इसे एक क्वेरी में जोड़ देंगे ताकि प्रत्येक निष्पादन का एक अलग शाब्दिक मूल्य हो। मैंने इसे एक संग्रहीत कार्यविधि में लपेटा है जो डायनामिक स्ट्रिंग एक्ज़ीक्यूशन (EXEC @QueryString) का उपयोग करके क्वेरी को कॉल करता है, इसलिए यह एक एडहॉक स्टेटमेंट की तरह व्यवहार करता है। इसे किसी संग्रहीत कार्यविधि के भीतर से कॉल करने का अर्थ है कि हम इसे ज्ञात संख्या में कई बार निष्पादित कर सकते हैं।

USE [WideWorldImporters];
GO
 
DROP PROCEDURE IF EXISTS dbo.[RandomSelects];  
GO
 
CREATE PROCEDURE dbo.[RandomSelects]
  @NumRows INT
AS
  DECLARE @ConcatString NVARCHAR(200);
  DECLARE @QueryString NVARCHAR(1000);
  DECLARE @RowLoop INT = 0;
  WHILE (@RowLoop < @NumRows)
  BEGIN
    SET @ConcatString = CAST((CONVERT (INT, RAND () * 2500) + 1) AS NVARCHAR(50))
      + CAST((CONVERT (INT, RAND () * 1000) + 1) AS NVARCHAR(50))
      + CAST((CONVERT (INT, RAND () * 500) + 1) AS NVARCHAR(50))
      + CAST((CONVERT (INT, RAND () * 1500) + 1) AS NVARCHAR(50));
 
    SELECT @QueryString = N'SELECT w.ColorID, s.StockItemName
      FROM Warehouse.Colors w
      JOIN Warehouse.StockItems s
      	ON w.ColorID = s.ColorID
      WHERE w.ColorName = ''' + @ConcatString + ''';';
 
    EXEC (@QueryString);
    SELECT @RowLoop = @RowLoop + 1;
  END
GO
 
DBCC FREEPROCCACHE;
GO
 
EXEC dbo.[RandomSelects] @NumRows = 10;
GO

क्रियान्वित करने के बाद, यदि हम योजना कैश की जाँच करते हैं, तो हम देख सकते हैं कि हमारे पास 10 अद्वितीय प्रविष्टियाँ हैं, जिनमें से प्रत्येक में 1 का निष्पादन_गणना है (विधेय के लिए अद्वितीय मान देखने के लिए यदि आवश्यक हो तो छवि को ज़ूम इन करें):

SELECT 
  [qs].[execution_count],
  [qs].[sql_handle],
  [qs].[query_hash],
  [qs].[query_plan_hash],
  [st].[text]
FROM sys.dm_exec_query_stats AS [qs] 
CROSS APPLY sys.dm_exec_sql_text ([qs].[sql_handle]) AS [st]
CROSS APPLY sys.dm_exec_query_plan ([qs].[plan_handle]) AS [qp]
WHERE [st].[text] LIKE '%Warehouse%'
ORDER BY [st].[text], [qs].[execution_count] DESC;
GO

अब हम लगभग समान संग्रहीत कार्यविधि बनाते हैं जो समान क्वेरी निष्पादित करती है, लेकिन पैरामीटरयुक्त:

USE [WideWorldImporters];
GO
 
DROP PROCEDURE IF EXISTS dbo.[SPRandomSelects];  
GO
 
CREATE PROCEDURE dbo.[SPRandomSelects]
  @NumRows INT
AS
  DECLARE @ConcatString NVARCHAR(200);
  DECLARE @QueryString NVARCHAR(1000);
  DECLARE @RowLoop INT = 0;
  WHILE (@RowLoop < @NumRows)
  BEGIN
    SET @ConcatString = CAST((CONVERT (INT, RAND () * 2500) + 1) AS NVARCHAR(50))
      + CAST((CONVERT (INT, RAND () * 1000) + 1) AS NVARCHAR(50))
      + CAST((CONVERT (INT, RAND () * 500) + 1) AS NVARCHAR(50))
      + CAST((CONVERT (INT, RAND () * 1500) + 1) AS NVARCHAR(50))
 
    SELECT w.ColorID, s.StockItemName
      FROM Warehouse.Colors w
      JOIN Warehouse.StockItems s
        ON w.ColorID = s.ColorID
      WHERE w.ColorName = @ConcatString;
 
    SELECT @RowLoop = @RowLoop + 1;
  END
GO
 
EXEC dbo.[SPRandomSelects] @NumRows = 10;
GO

योजना कैश के भीतर, 10 एडहॉक प्रश्नों के अलावा, हम पैरामीटरयुक्त क्वेरी के लिए एक प्रविष्टि देखते हैं जिसे 10 बार निष्पादित किया गया है। क्योंकि इनपुट पैरामीटरयुक्त है, भले ही बेतहाशा भिन्न स्ट्रिंग्स को पैरामीटर में पास किया गया हो, क्वेरी टेक्स्ट बिल्कुल समान है:

परीक्षण

अब जब हम समझ गए हैं कि प्लान कैश में क्या होता है, आइए अधिक लोड बनाते हैं। हम एक कमांड लाइन फ़ाइल का उपयोग करेंगे जो एक ही .sql फ़ाइल को 10 अलग-अलग थ्रेड्स पर कॉल करती है, जिसमें प्रत्येक फ़ाइल संग्रहीत कार्यविधि को 10,000 बार कॉल करती है। हम शुरू करने से पहले योजना कैश को साफ़ कर देंगे, और स्क्रिप्ट निष्पादित होने पर PerfMon के साथ कुल CPU% और SQL संकलन/सेकंड कैप्चर करेंगे।

Adhoc.sql फ़ाइल सामग्री:

EXEC [WideWorldImporters].dbo.[RandomSelects] @NumRows = 10000;

Parameterized.sql फ़ाइल सामग्री:

EXEC [WideWorldImporters].dbo.[SPRandomSelects] @NumRows = 10000;

उदाहरण कमांड फ़ाइल (नोटपैड में देखी गई) जो .sql फ़ाइल को कॉल करती है:

उदाहरण कमांड फ़ाइल (नोटपैड में देखी गई) जो 10 थ्रेड बनाती है, जिनमें से प्रत्येक Run_Adhoc.cmd फ़ाइल को कॉल करता है:

प्रश्नों के प्रत्येक सेट को कुल 100,000 बार चलाने के बाद, यदि हम प्लान कैश को देखते हैं तो हमें निम्नलिखित दिखाई देते हैं:

प्लान कैश में 10,000 से ज्यादा एडहॉक प्लान हैं। आपको आश्चर्य हो सकता है कि निष्पादित सभी 100,000 एडहॉक प्रश्नों के लिए कोई योजना क्यों नहीं है, और यह योजना कैश के काम करने के तरीके से संबंधित है (यह उपलब्ध मेमोरी के आधार पर आकार है, जब अप्रयुक्त योजनाएं पुरानी हो जाती हैं, आदि)। महत्वपूर्ण बात यह है कि तो बाकी कैश प्रकारों के लिए हम जो देखते हैं, उसकी तुलना में कई तदर्थ योजनाएँ मौजूद हैं।

PerfMon डेटा, नीचे रेखांकन किया गया, सबसे अधिक बता रहा है। 100,000 पैरामीटरयुक्त प्रश्नों का निष्पादन 15 सेकंड से भी कम समय में पूरा हुआ, और शुरुआत में संकलन/सेकंड में एक छोटा सा स्पाइक था, जो ग्राफ़ पर मुश्किल से ध्यान देने योग्य है। उसी संख्या के तदर्थ निष्पादन को पूरा होने में 60 सेकंड से अधिक का समय लगा, 2000 के करीब संकलन/सेकंड स्पाइकिंग के साथ, 45 सेकंड के निशान के आसपास 1000 के करीब जाने से पहले, सीपीयू के करीब या अधिकांश समय के लिए 100% पर।


सारांश

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. VDP उन्नत SQL एजेंट के साथ SQL डेटाबेस का बैकअप लेना

  2. कर्सर विकल्पों पर अनुवर्ती कार्रवाई

  3. उपयोगकर्ताओं, थ्रेड्स और पोस्ट को प्रबंधित करने के लिए बुनियादी डेटा संरचना की मॉडलिंग

  4. विंडोज सर्वर 2019 पर एक्सएएमपीपी सॉफ्टवेयर स्थापित और कॉन्फ़िगर करें

  5. अधिक शोप्लान सुधार? जी बोलिये!