এসকিউএল সার্ভারে, একটি নির্বাহী সঞ্চিত পদ্ধতিতে পাস হওয়া প্যারামিটারগুলির মানগুলি নির্ধারণ করার উপায় রয়েছে


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

আদর্শভাবে আমি দেখতে চাই যে প্যারামিটারগুলি চলমান প্রক্রিয়াটির জন্য কী ছিল যা আপত্তিজনক পরামিতিগুলির নির্দিষ্ট সেটটির জন্য এটি এত দিন চালিত করে।

এটা করার কোন উপায় আছে? ( এই প্রশ্নে অ্যারন বার্ট্র্যান্ড ডিবিসিসি ইনপুটবফার উল্লেখ করেছে , তবে আমি মনে করি না যে এটি এই সমস্যার জন্য উপযুক্ত)


ইনপুট পরামিতিগুলি ক্যাপচার করার জন্য বা রান সময়ে কী পাস হয়েছিল তা দেখার একমাত্র উপায় হ'ল মানগুলি এবং লগ ফাইলে কল করা। আপনি এটি রাইসিরররের সাহায্যে সহজেই করতে পারেন যদি আপনি এটিকে ত্রুটি লগতে দেখতে চান বা আরও কিছু চেষ্টা করে দেখতে চান তবে এটি কোনও বাহ্যিক ফাইলে লিখুন।
স্টিভ মঙ্গিয়ামালী

উত্তর:


16

এই তথ্যটি - রান-টাইম প্যারামিটার মানগুলি একটি সঞ্চিত পদ্ধতিতে (অর্থাত্ RPC কল) বা প্যারামিটারাইজড ক্যোয়ারিতে পাস করা হয়েছে - এটি কেবলমাত্র এসকিউএল ট্রেসের মাধ্যমে উপলব্ধ (এবং আমি এসকিউএল সার্ভারের নতুন সংস্করণগুলিতে সমতুল্য বর্ধিত ইভেন্ট হিসাবে ধরে নিই)। আপনি চলমান SQL সার্ভার প্রোফাইলার (এটা SQL সার্ভার দিয়ে আসে) এবং যেমন বিভিন্ন "সমাপ্ত" ঘটনা, নির্বাচন করে এই দেখতে পারেন: RPC:Completed, SP:Completed, এবং SQL:BatchCompleted। মানগুলি যেমন থাকবে তেমন আপনাকে "পাঠ্য ডেটা" ক্ষেত্রও নির্বাচন করতে হবে।

এই প্রশ্নের উপর আমার উত্তর এবং @ কিনের উত্তরের মধ্যে পার্থক্যটি হ'ল @ কিন এর উত্তর (যদি আমি ভুল না হয়ে থাকি, তবে এই ক্ষেত্রে আমি এটি সরিয়ে দেব) হয় না কেন:

  • আপনার নিজের ক্যোয়ারী পরিকল্পনা (এক্ষেত্রে এটিতে রানটাইম প্যারামিটার তথ্য থাকতে পারে তবে অন্য সেশন / এসপিআইডিগুলির জন্য নয়), বা
  • DMVs থেকে পরিকল্পনা (যে ক্ষেত্রে তারা উচিত শুধুমাত্র কম্পাইল পরামিতির মান, যা রানটাইম মান নয় থাকে)।

আমার উত্তরটি বর্তমানে চলমান অন্যান্য সেশনের জন্য প্যারামিটারের মানগুলি কেন্দ্রীভূত করার দিকে দৃষ্টি নিবদ্ধ করে । ডিএমভিগুলিতে নির্ভর করার সময়, রানটাইম প্যারামিটার মানটি সংকলিত প্যারামিটার মানের সমান কিনা তা জানার উপায় নেই। এবং এই প্রশ্নের প্রসঙ্গটি অন্যান্য সেশন / এসপিআইডি (এবং এসকিউএল সার্ভার ২০০৫-এ, যেখানে এসকিউএল সার্ভার ২০০৮ সালে প্রসারিত ইভেন্টগুলি প্রবর্তিত হয়েছিল) এর মাধ্যমে জমা দেওয়া প্রশ্নের অনুসন্ধানের রানটাইম মানটি খুঁজে বের করছে।


13

আপনি প্রকৃত বাস্তবায়ন পরিকল্পনাটি চালু করতে পারেন এবং তারপরে এক্সিকিউশন প্ল্যান এক্সএমএলটি দেখতে পারেন।

এখানে চিত্র বর্ণনা লিখুন

অথবা আপনি স্কয়ার সেন্ড্রির পরিকল্পনার এক্সপ্লোরার সরঞ্জামটি ব্যবহার করতে পারেন এবং 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

@ সলোমনরুতজকি ঠিক আছে।
এসকিউএল প্রোফাইলার ট্রেস হ'ল একমাত্র উপায় ( স্প্রোক সম্পাদনা না করে )।

আপনার স্প্রোক সম্পাদনা করুন:

যাইহোক , পরবর্তী সেরা জিনিসটি হল প্রশ্নে স্প্রোকটি সামান্য সম্পাদনা করা।
বর্তমান সময়ের সাথে শুরুতে একটি ডেটটাইম ভেরিয়েবল ঘোষণা করুন।
স্প্রোকের শেষে, সারণিতে স্প্রোক_সার্টটাইম, স্প্রোক_এন্ডটাইম এবং প্যারামিটার মানগুলি লগ ইন করুন।

আপনি কেবলমাত্র লগিংয়ের জন্য ডেটডিফ () ব্যবহার করার জন্য কিছু শর্তযুক্ত যুক্তি যুক্ত করতে পারতেন যখন স্প্রোক প্রক্রিয়াজাতকরণে বর্ধিত পরিমাণ সময় ব্যবহৃত হত।
এটি আপনার স্প্রোককে গতি বাড়িয়ে তুলতে পারে এবং স্প্রোক যখন টিপ-টপ চালাচ্ছে তার জন্য আপনার লগ টেবিলের স্পেস ব্যবহার হ্রাস করতে পারে।

তারপরে আপনার একটি লগ ফাইল রয়েছে যা আপনি কয়েক মাস ধরে জিজ্ঞাসা করতে পারেন এবং বিশ্লেষণ করতে পারেন (প্রোডে কোনও ট্রেস চলছে না)।
আপনি যখন আপনার স্প্রোক টিউন করার কাজ শেষ করেন, তখন আপনি যোগ করা টাইমার এবং লগার যুক্তির কয়েকটি লাইন মুছুন।

ক্যাশেড-প্ল্যান প্যারামিটার মানসমূহ:

আমার উল্লেখ করা উচিত যে আপনার লগ টেবিলের বর্তমান ক্যাশেড-প্ল্যান প্যারামিটার মানগুলি অন্তর্ভুক্ত করা আপনাকে নির্ধারণ করতে সহায়তা করতে পারে যে তারা পারফরম্যান্সের সমস্যাটিকে আরও জটিল করে তুলছে
আমি OPTIMIZE FORআমার স্প্রোকে প্যারামিটারগুলি কীভাবে পরিচালনা করব তা সেট করতে ব্যবহার করি যখন আমি জানি এটি ডেটা স্লাইসিং এবং ডাইটিংয়ের জন্য ব্যবহৃত হবে।
আমি দেখতে পেয়েছি যে OPTIMIZE FORasচ্ছিক ফিল্টারগুলির মতো প্যারামিটারগুলির সাথে একই স্প্রোক ব্যবহার করার সময় ফলনগুলি ধারাবাহিক এবং দ্রুত ফলাফল ব্যবহার করে ।
আপনি কীভাবে এটি পরিচালনা করতে পারেন তা নির্দিষ্ট করে বিবেচনা করার জন্য এটি অবশ্যই একটি কম পরিবর্তনশীল।

নীচে আপনি আপনার বাছাই-বিবৃতি নীচে কী যুক্ত করতে পারেন তার একটি উদাহরণ রয়েছে:

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" কোটে পরিকল্পনা যা আছে তাদের জন্য অ্যাকাউন্ট করে না 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
কোড শুধুমাত্র উত্তর নিরুৎসাহিত করা হয়। এই কোডটি কেন সমস্যার সমাধান করে তার একটি ব্যাখ্যা যোগ করার বিষয়ে বিবেচনা করুন। দেখুন কিভাবে উত্তর দিতে
পিটার Vandivier
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.