কীভাবে কোনও ক্যোয়ারী প্ল্যান তৈরির ব্যয়টি পরিমাপ করতে বা সন্ধান করতে হবে?


18

আমার একটি সাধারণ কেস রয়েছে যেখানে প্যারামিটার স্নিফিংয়ের কারণে পরিকল্পনার ক্যাশে একটি "খারাপ" কার্যকরকরণ পরিকল্পনা অবতীর্ণ হয়, যার ফলে আমার সঞ্চিত প্রক্রিয়াটির পরবর্তী মৃত্যুদন্ড কার্যকর খুব ধীর হয়ে যায়। আমি স্থানীয় ভেরিয়েবল OPTIMIZE FOR ... UNKNOWN, এবং দিয়ে এই সমস্যাটি "সমাধান" করতে পারি OPTION(RECOMPILE)। তবে, আমি ক্যোয়ারিতে ডুব দিয়ে এটিকে আরও অনুকূল করার চেষ্টা করতে পারি।

আমি কিনা তা নির্ধারণ করতে আমি চেষ্টা করছি উচিত ফিক্স সমস্যা সীমিত সময়ের প্রদত্ত আমি খরচ জানতে চাই: না এরকম। যেমনটি আমি দেখতে পাচ্ছি, আমি যদি কেবল এটির সাথে থাকি OPTION(RECOMPILE)তবে নেট এফেক্টটি হ'ল কোয়েরিটি চালানোর সময় প্রত্যেক সময় একটি ক্যোয়ারী পরিকল্পনা পুনরায় তৈরি করা হয় । সুতরাং, আমি মনে করি আমার জানা দরকার:

কোয়েরি প্ল্যান তৈরিতে কী খরচ হয় তা কীভাবে খুঁজে বের করবেন ?

আমার নিজের প্রশ্নের উত্তর দেওয়ার জন্য, আমি গুগল করেছি (যেমন এই কোয়েরি সহ ), এবং আমি dm_exec_query_statsডিএমভির জন্য কলামগুলির ডকুমেন্টেশনটি পেরিয়েছি । এই তথ্যটি অনুসন্ধানের জন্য আমি এসএসএমএসের "প্রকৃত ক্যোয়ারী প্ল্যান" এর জন্য আউটপুট উইন্ডোটিও পরিদর্শন করেছি। শেষ পর্যন্ত, আমি ডিবিএ.এসই অনুসন্ধান করেছি । তাদের কোনও উত্তর দেয়নি।

আমাকে কেউ বলতে পারবে? পরিকল্পনা তৈরির জন্য এটি কি প্রয়োজনীয় সময় খুঁজে পাওয়া বা পরিমাপ করা সম্ভব?


5
আমি বেঞ্জামিন নেভারেজের এসকিউএল সার্ভার ক্যোয়ারী অপ্টিমাইজারের অনুলিপিটি অনুলিপি করার সুপারিশ করব । এটা বিনামূল্যে. অধ্যায় 5 'অপ্টিমাইজেশন প্রক্রিয়া' আপনাকে আপনার প্রশ্নের জন্য সংকলনের সময় নিয়ে কাজ করতে সহায়তা করতে পারে। খুব কমপক্ষে, কোয়েরি প্ল্যান তৈরি করতে অপ্টিমাইজার কী মাধ্যমে যায় সে সম্পর্কে এটি তথ্যবহুল।
মার্ক সিনিংসন

উত্তর:


18

কোয়েরি প্ল্যান তৈরিতে কী খরচ হয় তা কীভাবে খুঁজে বের করবেন?

আপনি ক্যোয়ারী প্ল্যানে রুট নোডের বৈশিষ্ট্যগুলি দেখতে পারেন, উদাহরণস্বরূপ:

রুট বৈশিষ্ট্য নিষ্কাশন
(ফ্রি সেন্ট্রি ওয়ান প্ল্যান এক্সপ্লোরার থেকে স্ক্রিনশট )

প্ল্যান ক্যাশে জিজ্ঞাসা করেও এই তথ্য পাওয়া যায়, উদাহরণস্বরূপ নিম্নলিখিত সম্পর্কের উপর ভিত্তি করে কোয়েরি ব্যবহার করে:

WITH XMLNAMESPACES (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT 
    CompileTime = c.value('(QueryPlan/@CompileTime)[1]', 'int'),
    CompileCPU = c.value('(QueryPlan/@CompileCPU)[1]', 'int'),
    CompileMemory = c.value('(QueryPlan/@CompileMemory)[1]', 'int'),
    ST.[text],
    QP.query_plan
FROM sys.dm_exec_cached_plans AS CP
CROSS APPLY sys.dm_exec_query_plan(CP.plan_handle) AS QP
CROSS APPLY sys.dm_exec_sql_text(CP.plan_handle) AS ST
CROSS APPLY QP.query_plan.nodes('ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS N(c);

ফলাফল খণ্ড

এই ধরণের প্রশ্নগুলি পরিচালনা করার জন্য আপনার কাছে বিকল্পগুলির সম্পূর্ণ চিকিত্সার জন্য, এরল্যান্ড سومমারস্কোগের সম্প্রতি আপডেট হওয়া নিবন্ধটি দেখুন


4

"ব্যয়" ধরে নেওয়া সময়ের শর্তে (যদিও এটি নিশ্চিত নয় যে এটি ;-) এর শর্তে আরও কী হতে পারে তবে খুব কমপক্ষে আপনাকে নিম্নলিখিতগুলির মতো কিছু করে বোঝার পক্ষে সক্ষম হতে হবে:

DBCC FREEPROCCACHE WITH NO_INFOMSGS;

SET STATISTICS TIME ON;

EXEC sp_help 'sys.databases'; -- replace with your proc

SET STATISTICS TIME OFF;

"বার্তা" ট্যাবে রিপোর্ট করা প্রথম আইটেমটি হ'ল:

এসকিউএল সার্ভার পার্স এবং সংকলন সময়:

আমি এটি কমপক্ষে 10 বার চালাব এবং গড় "সিপিইউ" এবং "বিচ্ছিন্ন" মিলিসেকেন্ড উভয়ই।

আদর্শভাবে আপনি এটি প্রোডাকশনে চালাতেন যাতে আপনি একটি সঠিক সময়ের অনুমান করতে পারেন তবে খুব কমই লোকেদের প্রোডাকশনের পরিকল্পনার ক্যাশে সাফ করার অনুমতি দেওয়া হয়। ভাগ্যক্রমে, এসকিউএল সার্ভার ২০০৮ সালে শুরু হয়ে ক্যাশে থেকে একটি নির্দিষ্ট পরিকল্পনা সাফ করা সম্ভব হয়েছিল। কোন ক্ষেত্রে আপনি নিম্নলিখিতটি করতে পারেন:

DECLARE @SQL NVARCHAR(MAX) = '';
;WITH cte AS
(
  SELECT DISTINCT stat.plan_handle
  FROM sys.dm_exec_query_stats stat
  CROSS APPLY sys.dm_exec_text_query_plan(stat.plan_handle, 0, -1) qplan
  WHERE qplan.query_plan LIKE N'%sp[_]help%' -- replace "sp[_]help" with proc name
)
SELECT @SQL += N'DBCC FREEPROCCACHE ('
               + CONVERT(NVARCHAR(130), cte.plan_handle, 1)
               + N');'
               + NCHAR(13) + NCHAR(10)
FROM cte;
PRINT @SQL;
EXEC (@SQL);

SET STATISTICS TIME ON;

EXEC sp_help 'sys.databases' -- replace with your proc

SET STATISTICS TIME OFF;

যাইহোক, "খারাপ" ক্যাশেড পরিকল্পনার কারণ হিসাবে প্যারামিটারগুলিতে পাস করা মানগুলির পরিবর্তনশীলতার উপর নির্ভর করে, ডায়নামিক এসকিউএল OPTION(RECOMPILE)এবং এর মধ্যে একটি মাঝারি ক্ষেত্র বিবেচনা করার জন্য আরও একটি পদ্ধতি রয়েছে OPTION(OPTIMIZE FOR UNKNOWN)। হ্যাঁ, আমি এটা বলেছি। এবং আমি এমনকি অ-পরামিতিযুক্ত ডায়নামিক এসকিউএল বোঝাতে চাইছি। এখানে কেন।

আপনার কাছে পরিষ্কারভাবে এমন ডেটা রয়েছে যা অন্তত এক বা একাধিক ইনপুট প্যারামিটার মানের ক্ষেত্রে অসম বন্টন করে। উল্লিখিত বিকল্পগুলির ডাউনসাইডগুলি হ'ল:

  • OPTION(RECOMPILE)প্রতিটি মৃত্যুদন্ড কার্যকর করার জন্য একটি পরিকল্পনা তৈরি করে এবং আপনি কোনও প্ল্যান পুনরায় ব্যবহার থেকে কখনই উপকৃত হতে পারবেন না , এমনকি যদি আবার পাস হওয়া প্যারামিটার মানগুলি পূর্বের রান (গুলি) এর মতো হয়। প্রোকগুলির জন্য যা ঘন ঘন বলা হয় - প্রতি কয়েক সেকেন্ডে বা তার বেশি ঘন ঘন একবার - এটি আপনাকে মাঝে মাঝে ভয়ঙ্কর পরিস্থিতি থেকে রক্ষা করবে, তবে এখনও আপনাকে সর্বদা-সর্বশ্রেষ্ঠ নয় in

  • OPTION(OPTIMIZE FOR (@Param = value)) সেই নির্দিষ্ট মানের উপর ভিত্তি করে একটি পরিকল্পনা তৈরি করবে, যা বেশ কয়েকটি ক্ষেত্রে সহায়তা করতে পারে তবে তবুও আপনাকে বর্তমান ইস্যুতে খোলা রাখবে।

  • OPTION(OPTIMIZE FOR UNKNOWN)গড় বিতরণের পরিমাণের ভিত্তিতে একটি পরিকল্পনা তৈরি করবে, যা কিছু প্রশ্নে সহায়তা করবে তবে অন্যকে আঘাত করবে। এটি স্থানীয় ভেরিয়েবলগুলি ব্যবহার করার বিকল্প হিসাবে একই হওয়া উচিত।

ডায়নামিক এসকিউএল, তবে, সঠিকভাবে সম্পন্ন করার পরে , বিভিন্ন মানগুলিকে পাস করার জন্য তাদের নিজস্ব পৃথক ক্যোয়ারী পরিকল্পনাগুলি আদর্শ যা ভাল হতে পারে (ভাল, যতটা তারা করবে তত পরিমাণে)। এখানে মূল ব্যয় হ'ল বিভিন্ন মান যত বাড়তে চলেছে, ক্যাশে কার্যকর করার পরিকল্পনার সংখ্যা বৃদ্ধি পায় এবং তারা স্মৃতি গ্রহণ করে। গৌণ ব্যয়গুলি হ'ল:

  • এসকিউএল ইনজেকশনগুলি রোধ করতে স্ট্রিং প্যারামিটারগুলি বৈধকরণ করা দরকার

  • ডায়নামিক এসকিউএল-এর সরাসরি টেবিল অনুমতি প্রয়োজন হওয়ায় সম্ভবত আদর্শ সুরক্ষা বিমূর্ততা বজায় রাখতে একটি শংসাপত্র এবং শংসাপত্র ভিত্তিক ব্যবহারকারী সেট আপ করা প্রয়োজন।

সুতরাং, আমি এখানে এই পরিস্থিতিটি কীভাবে পরিচালনা করেছি যখন আমার কাছে প্রতি সেকেন্ডে একাধিকবার ডাকা হত এবং একাধিক টেবিল হিট হয়েছিল, যার প্রত্যেকটিতে লক্ষ লক্ষ সারি রয়েছে। আমি চেষ্টা করেছিলাম OPTION(RECOMPILE)কিন্তু 99% ক্ষেত্রে যে প্যারামিটার স্নিফিং / খারাপ ক্যাশেড প্ল্যান সমস্যা নেই তার ক্ষেত্রে এটি প্রক্রিয়াটির পক্ষে খুব ক্ষতিকারক প্রমাণিত। এবং দয়া করে মনে রাখবেন যে এগুলির একটিরও এর প্রায় 15 টি ক্যোয়ারী ছিল এবং তাদের মধ্যে কেবল 3 - 5 এখানে বর্ণিত হিসাবে ডায়নামিক এসকিউএল রূপান্তরিত হয়েছিল; গতিশীল এসকিউএল কোনও নির্দিষ্ট প্রশ্নের জন্য প্রয়োজনীয় না হলে ব্যবহৃত হত না।

  1. যদি সঞ্চিত পদ্ধতিতে একাধিক ইনপুট প্যারামিটার থাকে, তবে কলামগুলির সাথে কোনটি ব্যবহৃত হয় যা উচ্চতর বিতরণকারী ডেটা বিতরণ করে (এবং ফলে এই সমস্যাটি ঘটায়) এবং কোনটি কলামগুলির সাথে আরও বেশি বিতরণ রয়েছে তা ব্যবহার করে (এবং এটি হওয়া উচিত নয়) এই সমস্যা সৃষ্টি করে)।

  2. সমানভাবে বিতরণকৃত কলামগুলির সাথে সম্পর্কিত যেগুলি প্রোপ ইনপুট প্যারামিগুলির জন্য পরামিতিগুলি ব্যবহার করে ডায়নামিক এসকিউএল স্ট্রিং তৈরি করুন। এই প্যারামিটারাইজেশন এই প্রশ্নের সাথে সম্পর্কিত ক্যাশে কার্যকরকরণ পরিকল্পনার ফলস্বরূপ বৃদ্ধি হ্রাস করতে সহায়তা করে।

  3. অবশিষ্ট পরামিতিগুলির জন্য যা উচ্চ বৈচিত্রপূর্ণ বিতরণের সাথে যুক্ত, তাদের আক্ষরিক মান হিসাবে ডায়নামিক এসকিউএল হিসাবে যুক্ত করা উচিত। যেহেতু একটি অনন্য ক্যোয়ারী ক্যোয়ারী পাঠ্যের যে কোনও পরিবর্তন দ্বারা নির্ধারিত হয়, WHERE StatusID = 1হ'ল আলাদা ক্যোয়ারী হওয়া এবং তাই, আলাদা ক্যোয়ারী পরিকল্পনা থাকার চেয়ে WHERE StatusID = 2

  4. কোয়েরির পাঠ্যের সাথে প্রনাক্ট ইনপুট প্যারামিটারগুলির মধ্যে যদি কোনও স্ট্রিং থাকে তবে এসকিউএল ইনজেকশন থেকে রক্ষা করার জন্য তাদের বৈধতা দেওয়া দরকার (যদিও স্ট্রিংগুলি পাস করা হচ্ছে যদি এটির সম্ভাবনা কম থাকে তবে অ্যাপ্লিকেশন এবং কোনও ব্যবহারকারী নয়, তবে এখনও)। কমপক্ষে REPLACE(@Param, '''', '''''')সিঙ্গেল-কোটগুলি একক-কোট হয়ে যায় বলে নিশ্চিত হয়ে নিন।

  5. যদি প্রয়োজন হয় তবে একটি শংসাপত্র তৈরি করুন যা ব্যবহারকারীর তৈরি করতে এবং সঞ্চিত পদ্ধতিতে স্বাক্ষর করার জন্য ব্যবহার করা হবে যেমন সরাসরি টেবিলের অনুমতি কেবল নতুন শংসাপত্র ভিত্তিক ব্যবহারকারীকে দেওয়া হবে এবং [public]অন্যথায় এই জাতীয় অনুমতি না থাকা ব্যবহারকারীদের বা না ।

উদাহরণস্বরূপ:

CREATE PROCEDURE MySchema.MyProc
(
  @Param1 INT,
  @Param2 DATETIME,
  @Param3 NVARCHAR(50)
)
AS
SET NOCOUNT ON;

DECLARE @SQL NVARCHAR(MAX);

SET @SQL = N'
     SELECT  tab.Field1, tab.Field2, ...
     FROM    MySchema.SomeTable tab
     WHERE   tab.Field3 = @P1
     AND     tab.Field8 >= CONVERT(DATETIME, ''' +
  CONVERT(NVARCHAR(50), @Param2, 121) +
  N''')
     AND     tab.Field2 LIKE N''' +
  REPLACE(@Param3, N'''', N'''''') +
  N'%'';';

EXEC sp_executesql
     @SQL,
     N'@P1 INT',
     @P1 = @Param1;

উত্তর দেওয়ার জন্য (বেশ কিছুটা) সময় দেওয়ার জন্য ধন্যবাদ! আমি কিভাবে কম্পাইল সময় যাবেন সে বিষয়ে প্রথম বিট সম্পর্কে একটু সন্দিহান যদিও নই, প্রদত্ত যে এটি একটি ফ্যাক্টর 3 ফলাফলের আমি ব্যবহার দ্বারা পেতে কম @ PaulWhite এর পদক্ষেপ । - ডায়নামিক এসকিউএল বিটের দ্বিতীয়টি আকর্ষণীয় (যদিও এটি বাস্তবায়নের জন্য সময়ও লাগবে; কমপক্ষে OPTIONআমার ক্যোয়ারীর উপরে চড় মারার চেয়েও বেশি ), এবং এই স্প্রোকটি ইন্টিগ্রেশন পরীক্ষায় ভালভাবে জড়িত হওয়ায় আমাকে খুব বেশি ক্ষতি করবেন না । - যাই হোক না কেন: আপনার অন্তর্দৃষ্টি জন্য ধন্যবাদ!
জেরোইন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.