SQL सर्वर में, निष्पादित निष्पादन प्रक्रिया में दिए गए मापदंडों के मूल्यों को निर्धारित करने का एक तरीका है


13

निष्पादित स्टोरेज प्रक्रिया को निर्धारित करने का एक तरीका "डायनेमिक मैनेजमेंट" विधियों का उपयोग करना है, जैसे:

SELECT 
    sqlText.Text, req.* 
FROM 
    sys.dm_exec_requests req
OUTER APPLY 
    sys.dm_exec_sql_text(req.sql_handle) AS sqltext

हालाँकि, यह केवल संग्रहीत कार्यविधि के बनाएँ कथन का पाठ प्रदर्शित करता है। उदाहरण के लिए:

CREATE PROCEDURE IMaProcedure @id int AS SELECT * FROM AllTheThings Where id = @id

आदर्श रूप से मैं यह देखना चाहूंगा कि रनिंग प्रक्रिया के लिए पैरामीटर क्या थे जो विशेष रूप से आक्रामक मापदंडों के सेट के लिए इसे चलाने के लिए पैदा कर रहे हैं।

क्या ऐसा करने के लिए कोई रास्ता है? ( इस प्रश्न में हारून बर्ट्रेंड ने DBCC InputBuffer का उल्लेख किया है , लेकिन मुझे नहीं लगता कि यह समस्या के लिए उचित है।)


वास्तव में इनपुट मापदंडों को कैप्चर करने या रन टाइम में क्या पारित हुआ था यह देखने का एकमात्र तरीका मूल्यों और कॉल को लॉग फ़ाइल में लॉग करना है। आप इसे आसानी से RAISEERROR के साथ कर सकते हैं यदि आप इसे त्रुटि लॉग में देखना चाहते हैं या थोड़े और प्रयास के साथ, तो इसे किसी बाहरी फ़ाइल में लिखें।
स्टीव मैंगमेली

जवाबों:


16

यह जानकारी - रन-टाइम पैरामीटर मान एक संग्रहीत कार्यविधि (यानी RPC कॉल) या पैरामीटर किए गए क्वेरी में पारित हुई - केवल SQL ट्रेस के माध्यम से उपलब्ध है (और मैं SQL सर्वर के नए संस्करणों में बराबर विस्तारित ईवेंट मानता हूं)। आपके द्वारा चलाए जा एसक्यूएल सर्वर प्रोफाइलर (यह एसक्यूएल सर्वर के साथ आता है) और इस तरह के रूप में विभिन्न "पूर्ण" घटनाओं, का चयन करके इस देख सकते हैं: RPC:Completed, SP:Completed, और SQL:BatchCompleted। आपको "TextData" फ़ील्ड का चयन करने की भी आवश्यकता है क्योंकि मान इसमें होंगे।

इस प्रश्न पर मेरे उत्तर और @ परिजनों के उत्तर के बीच का अंतर यह है कि @ परिजन का उत्तर (जब तक कि मुझसे कोई गलती नहीं है, जिस स्थिति में मैं इसे हटा दूंगा) या तो प्राप्त करने पर ध्यान केंद्रित करता है:

  • आपकी स्वयं की क्वेरी योजना (किस स्थिति में इसमें रनटाइम पैरामीटर जानकारी हो सकती है, लेकिन अन्य सत्रों / SPIDs के लिए नहीं), या
  • DMV से योजनाएं (जिस स्थिति में उन्हें केवल संकलित पैरामीटर मान होना चाहिए , जो रनटाइम मान नहीं हैं)।

मेरा उत्तर वर्तमान में चल रहे अन्य सत्रों के लिए पैरामीटर मान प्राप्त करने पर केंद्रित है । DMV पर भरोसा करते समय, यह जानने का कोई तरीका नहीं है कि रनटाइम पैरामीटर मान संकलित पैरामीटर मान के समान है या नहीं। और इस सवाल का संदर्भ अन्य सत्रों / एसपीआईडी ​​(और एसक्यूएल सर्वर 2005 में, जबकि एक्सटेंडेड इवेंट्स एसक्यूएल सर्वर 2008 में पेश किया गया था) के माध्यम से प्रस्तुत किए जा रहे प्रश्नों के रनटाइम मूल्य को ट्रैक कर रहा है।


13

आप वास्तविक निष्पादन योजना को चालू कर सकते हैं और फिर निष्पादन योजना XML को देख सकते हैं।

यहाँ छवि विवरण दर्ज करें

या आप sql संतरी के प्लान एक्सप्लोरर टूल का उपयोग कर सकते हैं और उस parametersटैब को देख सकते हैं जो वास्तविक निष्पादन योजना के लिए compiled valueऔर उसकी सूची देगा run time value

यदि आप वास्तविक योजना को चालू नहीं कर सकते हैं तो आप नीचे बताए अनुसार योजना कैश में देख सकते हैं।

-- borrowed from  Erland Sommarskog
-- Link : http://www.sommarskog.se/query-plan-mysteries.html#dmvgettingplans
-- Remember that you are looking at the estimated plan so the actual no. of rows and actual executions wont be there ! <-- Important why a particular plan is bad.

DECLARE @dbname    nvarchar(256),
        @procname  nvarchar(256)
SELECT @dbname = 'Northwind',  -- Your DB name
       @procname = 'dbo.List_orders_11' -- The SP that you want to get parameters for !

; WITH basedata AS (
   SELECT qs.statement_start_offset/2 AS stmt_start,
          qs.statement_end_offset/2 AS stmt_end,
          est.encrypted AS isencrypted, est.text AS sqltext,
          epa.value AS set_options, qp.query_plan,
          charindex('<ParameterList>', qp.query_plan) + len('<ParameterList>')
             AS paramstart,
          charindex('</ParameterList>', qp.query_plan) AS paramend
   FROM   sys.dm_exec_query_stats qs
   CROSS  APPLY sys.dm_exec_sql_text(qs.sql_handle) est
   CROSS  APPLY sys.dm_exec_text_query_plan(qs.plan_handle,
                                            qs.statement_start_offset,
                                            qs.statement_end_offset) qp
   CROSS  APPLY sys.dm_exec_plan_attributes(qs.plan_handle) epa
   WHERE  est.objectid  = object_id (@procname)
     AND  est.dbid      = db_id(@dbname)
     AND  epa.attribute = 'set_options'
), next_level AS (
   SELECT stmt_start, set_options, query_plan,
          CASE WHEN isencrypted = 1 THEN '-- ENCRYPTED'
               WHEN stmt_start >= 0
               THEN substring(sqltext, stmt_start + 1,
                              CASE stmt_end
                                   WHEN 0 THEN datalength(sqltext)
                                   ELSE stmt_end - stmt_start + 1
                              END)
          END AS Statement,
          CASE WHEN paramend > paramstart
               THEN CAST (substring(query_plan, paramstart,
                                   paramend - paramstart) AS xml)
          END AS params
   FROM   basedata
)
SELECT set_options AS [SET], n.stmt_start AS Pos, n.Statement,
       CR.c.value('@Column', 'nvarchar(128)') AS Parameter,
       CR.c.value('@ParameterCompiledValue', 'nvarchar(128)') AS [Sniffed Value],
       CAST (query_plan AS xml) AS [Query plan]
FROM   next_level n
CROSS  APPLY   n.params.nodes('ColumnReference') AS CR(c)
ORDER  BY n.set_options, n.stmt_start, Parameter

5
योजना कैश में केवल विशिष्ट रन के लिए मूल्यों के बजाय संकलित मान हैं। प्रोयलर Showplan XML Statistics Profileमें ईवेंट का उपयोग वास्तविक योजना प्राप्त करने के लिए भी कर सकते हैं, हालांकि यदि प्रोइलर को बाहर निकालते हैं तो इसे प्राप्त करने के कम गहन तरीके होंगे।
मार्टिन स्मिथ

1

@SolomonRutzky सही है।
SQL Profiler Trace एकमात्र तरीका है ( बिना Sproc के संपादन के )।

अपना स्थान संपादित करें:

हालांकि , अगली सबसे अच्छी बात यह है कि प्रश्न में स्प्रो को थोड़ा संपादित किया जाए।
वर्तमान समय के साथ शुरुआत में दिनांक समय चर घोषित करें।
Sproc के अंत में, एक मेज पर Sproc_StartTime, Sproc_EndTime, और Parameter मान लॉग करें।

तुम भी केवल लॉगिंग के लिए एक डेटडिफ़ () का उपयोग करने के लिए कुछ सशर्त तर्क जोड़ सकते हैं जब स्प्रो प्रसंस्करण में समय की एक विस्तारित राशि का उपयोग किया गया था।
जब स्पोक टिप-टॉप चल रहा हो, तो इसके लिए अपने स्पोक में तेजी लाएं और अपने लॉग टेबल के स्पेस कंजम्पशन को कम करें।

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

कैश्ड-प्लान पैरामीटर मान:

मुझे यह उल्लेख करना चाहिए कि आपकी लॉग टेबल में करंट कैश्ड-प्लान पैरामीटर मान सहित आपको यह निर्धारित करने में मदद कर सकता है कि क्या वे प्रदर्शन समस्या को कम कर रहे हैं ।
मैं OPTIMIZE FORयह निर्धारित करने के लिए उपयोग करता हूं कि मेरे स्पोक में पैरामीटर्स को कैसे हैंडल किया जाए जब मुझे पता है कि इसका उपयोग डेटा को स्लाइसिंग और डिलिंग के लिए किया जाएगा।
मुझे लगता है कि वैकल्पिक फिल्टर केOPTIMIZE FOR रूप में पैरामीटर्स के साथ एक ही स्पोक का उपयोग करते समय पैदावार लगातार और तेज परिणाम का उपयोग करना । यह निश्चित रूप से विचार करने के लिए एक कम चर है कि आप उन्हें कैसे संभालना है।

नीचे एक उदाहरण है कि आप अपने चयन-कथन के नीचे क्या जोड़ सकते हैं:

OPTION(OPTIMIZE FOR (@SiteID = 'ABC',
                     @LocationID = NULL, @DepartmentID = NULL,
                     @EmployeeID = NULL, @CustomerID = NULL,
                     @ProductID = NULL, @OrderID = NULL, @OrderStatusID = NULL,
                     @IncludedCancelledOrders = 1,
                     @StartDate UNKNOWN, @EndDate UNKNOWN))

0

मैंने देखा है जब टुकड़ा योजना एक्सएमएल और बाहर ParameterCompiledValue पुल है कि पहले "basedata" CTE योजनाओं जो है के लिए खाते में नहीं है Erland Sommarskog की क्वेरी का उपयोग कर चेतावनी (जैसे अंतर्निहित रूपांतरण) CHARINDEX (बिल्ट-इन समारोह) पहली अभिव्यक्ति से मिलता जुलता स्ट्रिंग के लिए दिखता है के रूप में इनपुट (यानी) और ऐसी चेतावनियाँ इन्हीं वाक्यांशों / नोड्स का उपयोग करती हैं।

इसलिए मैं नीचे संशोधित अनुभाग के साथ इस अनुभाग को प्रतिस्थापित करने का प्रस्ताव करता हूं:

      CHARINDEX('<ParameterList>', qp.query_plan) + LEN('<ParameterList>') AS paramstart,
      CHARINDEX('</ParameterList>', qp.query_plan) AS paramend

संशोधित अनुभाग:

       CHARINDEX('<ParameterList><ColumnReference', qp.query_plan) + LEN('<ParameterList>') AS paramstart,
       CHARINDEX('</ParameterList></QueryPlan>', qp.query_plan) AS paramend

Disallowed implicit conversion from data type xml to data type varchar, table 'sys.dm_exec_query_plan', column 'query_plan'. Use the CONVERT function to run this query.
मैट

-1
SELECT DB_NAME(req.database_id),
sqltext.TEXT,
req.session_id,
req.status,
req.start_time,
req.command,
req.cpu_time,
req.total_elapsed_time ,   REPLACE(REPLACE(REPLACE(REPLACE(
CONVERT(VARCHAR(MAX), CONVERT(XML, REPLACE( query_plan, 'xmlns="','xmlns1="')).query('//        ParameterList/ColumnReference')),
'<ColumnReference Column="','declare '),
'" ParameterDataType="',' '),
'" ParameterCompiledValue="(',' = '),
')"/>', CONCAT(';', CHAR(10) , CHAR(13))) ParameterList
FROM sys.dm_exec_requests req
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqltext 
 CROSS  APPLY sys.dm_exec_text_query_plan(plan_handle, statement_start_offset, statement_end_offset) qp
order by req.total_elapsed_time desc 

2
कोड केवल उत्तर हतोत्साहित करते हैं। इस कोड की समस्या को हल करने के बारे में स्पष्टीकरण देने पर विचार करें। देखें कैसे जवाब दें
पीटर वांडिवियर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.