প্যারামিটার স্নিফিং বনাম ভারিবেলস বনাম রিকম্পাইল বনাম অপেশনের জন্য অপ্টিমাইজ


40

তাই আজ সকালে আমাদের দীর্ঘকালীন সমস্যা সৃষ্টি হয়েছে (30 সেকেন্ড + রান সময়)। প্যারামিটার স্নিফিংয়ের জন্য দোষ ছিল কিনা তা আমরা পরীক্ষা করার সিদ্ধান্ত নিয়েছি। সুতরাং, আমরা প্রকল্পটি পুনরায় লিখন করেছি এবং আগত পরামিতিগুলি ভেরিয়েবলগুলিতে সেট করেছি যাতে প্যারামিটার স্নিফিংকে পরাজিত করতে পারে। একটি চেষ্টা / সত্য পদ্ধতির। বাম, ক্যোয়ারির সময় উন্নতি হয়েছে (1 সেকেন্ডের কম) কোয়েরি পরিকল্পনার দিকে তাকানোর সময় উন্নতিগুলি কোনও সূচকে পাওয়া গেছে যে মূলটি ব্যবহার করছে না।

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

সুতরাং, আমার প্রশ্নটি হ'ল ... খালি প্ল্যান ক্যাশে যখন আমরা একই ধীর অনুসন্ধানটি পাই তখন কীভাবে পরামিতিগুলি কীভাবে দোষ দেওয়া যায় ... স্নিফ করার কোনও প্যারামিটার থাকতে হবে না ???

আমরা কি পরিবর্তে পরিকল্পনার ক্যাশের সাথে সম্পর্কিত নয় টেবিলের পরিসংখ্যান দ্বারা প্রভাবিত হচ্ছি? এবং যদি তা হয় তবে কেন ভেরিয়েবলের সাহায্যে আগত পরামিতিগুলি সেট করা হবে ??

আরও পরীক্ষামূলক আমরা আরও দেখা গেছে বিকল্প (নিখুত জন্য অজানা) proc এর অভ্যন্তরীণ উপর ঢোকাতে DID প্রত্যাশিত উন্নত পরিকল্পনা করুন।

সুতরাং, আপনারা কেউ কেউ আমার চেয়ে বেশি স্মার্ট, এই ধরণের ফলাফল তৈরি করার জন্য আপনি কি কিছু সংকেত দিতে পারবেন?

অন্য নোটে, ধীর পরিকল্পনার কারণও তাড়াতাড়ি বাতিল GoodEnoughPlanFoundহয়ে যায় যখন দ্রুত পরিকল্পনার প্রকৃত পরিকল্পনার কোনও প্রাথমিক গর্ভপাতের কারণ নেই।

সংক্ষেপে

  • আগত প্যারামিটারগুলির বাইরে ভেরিয়েবল তৈরি করা (1 সেকেন্ড)
  • রিকম্পাইল সহ (30+ সেকেন্ড)
  • ডিবিসিসি ফ্রিপ্রোকা (30+ সেকেন্ড)
  • বিকল্প (ইউকেউনের জন্য অপ্টিমাইজ করুন) (1 সেকেন্ড)

হালনাগাদ:

এখানে ধীর সম্পাদন পরিকল্পনা দেখুন: https://www.DPboxbox.com/s/cmx2lrsea8q8mr6/plan_slow.xml

দ্রুত বাস্তবায়ন পরিকল্পনা এখানে দেখুন: https://www.DPboxbox.com/s/b28x6a01w7dxsed/plan_fast.xml

দ্রষ্টব্য: সারণী, স্কিমা, সুরক্ষার কারণে অবজেক্টের নাম পরিবর্তন করা হয়েছে।

উত্তর:


43

কোয়েরিটি হ'ল

SELECT SUM(Amount) AS SummaryTotal
FROM   PDetail WITH(NOLOCK)
WHERE  ClientID = @merchid
       AND PostedDate BETWEEN @datebegin AND @dateend 

সারণীতে 103,129,000 সারি রয়েছে।

দ্রুত পরিকল্পনা ক্লায়েন্টআইড দ্বারা তারিখের একটি অবশিষ্টাংশের শিকারের সাথে দেখা হবে তবে এটি পুনরুদ্ধার করতে 96 টি লুকআপ করা দরকার Amount<ParameterList>পরিকল্পনা বিভাগে নিম্নরূপ।

        <ParameterList>
          <ColumnReference Column="@dateend" 
                           ParameterRuntimeValue="'2013-02-01 23:59:00.000'" />
          <ColumnReference Column="@datebegin" 
                           ParameterRuntimeValue="'2013-01-01 00:00:00.000'" />
          <ColumnReference Column="@merchid" 
                           ParameterRuntimeValue="(78155)" />
        </ParameterList>

ধীর পরিকল্পনাটি তারিখ অনুসারে আপাতদৃষ্টিতে দেখায় এবং ক্লায়েন্টআইডির অবশিষ্টাংশের ভবিষ্যদ্বাণীটি মূল্যায়নের জন্য এবং পরিমাণটি পুনরুদ্ধার করার জন্য নজর রাখে (আনুমানিক 1 বনাম প্রকৃত 7,388,383)। <ParameterList>অধ্যায়

        <ParameterList>
          <ColumnReference Column="@EndDate" 
                           ParameterCompiledValue="'2013-02-01 23:59:00.000'" 
                           ParameterRuntimeValue="'2013-02-01 23:59:00.000'" />
          <ColumnReference Column="@BeginDate" 
                           ParameterCompiledValue="'2013-01-01 00:00:00.000'"               
                           ParameterRuntimeValue="'2013-01-01 00:00:00.000'" />
          <ColumnReference Column="@ClientID" 
                           ParameterCompiledValue="(78155)" 
                           ParameterRuntimeValue="(78155)" />
        </ParameterList>

এই দ্বিতীয় যদি ParameterCompiledValueহয় না খালি। এসকিউএল সার্ভার সফলভাবে ক্যোয়ারীতে ব্যবহৃত মানগুলি স্নিগ্ধ করে।

"এসকিউএল সার্ভার 2005 প্র্যাক্টিকাল ট্রাবলশুটিং" বইয়ের স্থানীয় ভেরিয়েবলগুলি ব্যবহার করার কথা রয়েছে

পরামিতি স্নিফিংকে পরাভূত করতে স্থানীয় পরিবর্তনগুলি ব্যবহার করা মোটামুটি সাধারণ কৌশল, তবে OPTION (RECOMPILE)এবং OPTION (OPTIMIZE FOR)ইঙ্গিতগুলি ... সাধারণত আরও মার্জিত এবং কিছুটা ঝুঁকিপূর্ণ সমাধান হয়


বিঃদ্রঃ

এসকিউএল সার্ভার ২০০৫-এ, বিবৃতি স্তরের সংকলন ক্যোয়ারীর প্রথম প্রয়োগের ঠিক আগে পর্যন্ত কোনও সঞ্চিত পদ্ধতিতে পৃথক বিবৃতি সংকলনের অনুমতি দেয়। ততক্ষণে স্থানীয় ভেরিয়েবলের মান জানা যাবে। তাত্ত্বিকভাবে এসকিউএল সার্ভার এটি ব্যবহার করে প্যারামিটারগুলি যেভাবে শুকিয়ে যায় সেভাবে স্থানীয় ভেরিয়েবলের মানগুলি স্নিগ্ধ করতে পারে। তবে এসকিউএল সার্ভার 7.0 এবং এসকিউএল সার্ভার 2000+ এ প্যারামিটার স্নিফিংকে পরাস্ত করতে স্থানীয় ভেরিয়েবলগুলি ব্যবহার করা সাধারণ কারণ, এসকিউএল সার্ভার 2005-এ স্থানীয় ভেরিয়েবলগুলির স্নিফিং সক্ষম করা হয়নি It এটি ভবিষ্যতে এসকিউএল সার্ভার রিলিজে সক্ষম হতে পারে যদিও এটি একটি ভাল আপনার যদি কোন পছন্দ থাকে তবে এই অধ্যায়ে বর্ণিত অন্যান্য বিকল্পগুলির মধ্যে একটির ব্যবহার করার কারণ।


দ্রুত পরীক্ষা থেকে এই পরিণতিটি উপরে বর্ণিত আচরণটি ২০০৮ এবং ২০১২ সালে এখনও একই রকম এবং চলকগুলি স্থগিত সংকলনের জন্য স্নিগ্ধ করা হয় না তবে কেবল যখন একটি স্পষ্ট OPTION RECOMPILEইঙ্গিত ব্যবহার করা হয়।

DECLARE @N INT = 0

CREATE TABLE #T ( I INT );

/*Reference to #T means this statement is subject to deferred compile*/
SELECT *
FROM   master..spt_values
WHERE  number = @N
       AND EXISTS(SELECT COUNT(*) FROM #T)

SELECT *
FROM   master..spt_values
WHERE  number = @N
OPTION (RECOMPILE)

DROP TABLE #T 

বিলম্বিত সংকলন সত্ত্বেও ভেরিয়েবলটি শুকানো হয় না এবং আনুমানিক সারির সংখ্যাটি সঠিক নয়

হিসাব বনাম আসল

সুতরাং আমি ধরে নিই যে ধীর পরিকল্পনাটি ক্যোয়ারীর একটি প্যারামিটারাইজড সংস্করণ সম্পর্কিত।

ParameterCompiledValueসমান ParameterRuntimeValueতাই এই টিপিক্যাল প্যারামিটার আঘ্রাণ (যেখানে পরিকল্পনা মান এক সেট তারপর মূল্যবোধের অন্য সেট চালানোর জন্য কম্পাইল করা হয়েছিল) নয় পরামিতি সব জন্য।

সমস্যাটি হ'ল সঠিক পরামিতি মানগুলির জন্য যে পরিকল্পনাটি সংকলিত হয়েছে তা অনুপযুক্ত।

আপনি সম্ভবত বর্ণনা তারিখ আরোহী সঙ্গে সমস্যা আঘাত করছে এখানে এবং এখানে । এসকিউএল সার্ভার স্বয়ংক্রিয়ভাবে আপনার জন্য পরিসংখ্যান আপডেট করার আগে ১০০ মিলিয়ন সারি সহ একটি টেবিলের জন্য আপনার 20 মিলিয়ন সন্নিবেশ করাতে হবে (বা অন্যথায় সংশোধন করতে হবে)। দেখে মনে হয় গতবারে এগুলি আপডেট করা হয়েছিল শূন্য সারিতে ক্যোয়ারিতে তারিখের সীমা মেলে তবে এখন million মিলিয়ন করে।

আপনি আরও ঘন ঘন পরিসংখ্যান আপডেটের সময়সূচী তৈরি করতে পারেন, ট্রেস ফ্ল্যাগগুলি বিবেচনা 2389 - 90করতে বা ব্যবহার করতে পারেন OPTIMIZE FOR UKNOWNযাতে datetimeকলামটিতে বর্তমানে বিভ্রান্তিকর পরিসংখ্যান ব্যবহার করতে সক্ষম হওয়ার চেয়ে এটি অনুমানের পিছনে পড়ে যায় ।

এটি এসকিউএল সার্ভারের পরবর্তী সংস্করণে (2012 এর পরে) প্রয়োজন হতে পারে না। কোনও সম্পর্কিত কানেক্ট আইটেমটিতে আকর্ষণীয় প্রতিক্রিয়া রয়েছে

মাইক্রোসফ্ট 8/28/2012 এ 1:35 অপরাহ্ন পোস্ট করেছে
আমরা পরবর্তী বড় রিলিজের জন্য একটি কার্ডিনালিটি অনুমানের বর্ধন করেছি যা মূলত এটিকে ঠিক করে দেয়। আমাদের পূর্বরূপগুলি প্রকাশিত হওয়ার পরে বিশদগুলির জন্য যোগাযোগ করুন। এরিক

এই 2014 এর উন্নতিটি নিবন্ধের শেষের দিকে বেনিয়ামিন নেভারেজকে দেখেছে:

নিউ SQL সার্ভার Cardinality মূল্নির্ধারক এ ফার্স্ট লুক

এটি প্রদর্শিত হবে যে নতুন কার্ডিনালিটি অনুমানকারী পিছিয়ে পড়বে এবং 1 সারিটির প্রাক্কলন না দিয়ে এই ক্ষেত্রে গড় ঘনত্ব ব্যবহার করবে।

2014 কার্ডিনালিটি অনুমানকারী এবং আরোহী কী সমস্যা সম্পর্কে কিছু অতিরিক্ত বিশদ এখানে:

এসকিউএল সার্ভারে নতুন কার্যকারিতা 2014 - পার্ট 2 - নতুন কার্ডিনালিটির অনুমান


29

সুতরাং, আমার প্রশ্নটি হ'ল ... আমরা যখন খালি পরিকল্পনার ক্যাশে একই ধীর ক্যোয়ারীটি পাই তখন পরামিতিগুলি কীভাবে দোষযুক্ত হতে পারে ... শুঁকানোর কোনও প্যারামিটার থাকতে হবে না?

এসকিউএল সার্ভার যখন প্যারামিটার মানগুলি যুক্ত একটি কোয়েরি সংকলন করে, এটি কার্ডিনালাইটি (সারি গণনা) অনুমানের জন্য সেই পরামিতিগুলির নির্দিষ্ট মানগুলিকে স্নিগ্ধ করে। আপনার ক্ষেত্রে, নির্দিষ্ট মান @BeginDate, @EndDateএবং @ClientIDএকটি মৃত্যুদন্ড পরিকল্পনা চয়নের ব্যবহার করা হয়। আপনি এখানে এবং এখানে প্যারামিটার স্নিফিং সম্পর্কে আরও বিশদ জানতে পারেন । আমি এই ব্যাকগ্রাউন্ড লিঙ্কগুলি সরবরাহ করছি কারণ উপরের প্রশ্নটি আমাকে ধারণাটি অসম্পূর্ণভাবে বর্তমানে উপলব্ধি করাতে বাধ্য করে - যখন কোনও পরিকল্পনা সংকলন করা হয় তখন সবসময় ঘামের প্যারামিটার মান থাকে values

যাইহোক, এগুলি সবই পয়েন্টের পাশে, কারণ মার্টিন স্মিথ যেভাবে পয়েন্ট দিয়েছিলেন প্যারামিটার স্নিফিং এখানে সমস্যা নয়। সময় ধীর ক্যোয়ারী সংকলিত হয়েছিল এ পরিসংখ্যান নির্দেশিত এর শোঁকা মানের জন্য কোন সারি ছিল @BeginDateএবং @EndDate:

ধীরগতির পরিকল্পনা স্নিগ্ধ মান

শুকনো মানগুলি অতি সাম্প্রতিক, যা আরোহণের মূল সমস্যাটি মার্টিনের উল্লেখ করেছে suggest যেহেতু তারিখগুলিতে সূচকটি সন্ধান করা হয় কেবলমাত্র একটি একক সারিতে প্রত্যাশিত, তাই অপ্টিমাইজার একটি পরিকল্পনা বেছে নিয়েছে যা কীট ClientIDলুকআপ অপারেটরের নিকটকে অবশিষ্টাংশ হিসাবে চাপ দেয়।

একক সারির প্রাক্কলন অপটিমাইজার আরও ভাল পরিকল্পনার সন্ধান বন্ধ করে দেওয়ার জন্য, একটি ভাল পর্যাপ্ত পরিকল্পনার সন্ধানের বার্তাটি ফিরে আসার কারণ। একক সারির প্রাক্কলন সহ ধীর পরিকল্পনার আনুমানিক মোট ব্যয়টি কেবল 0.013136 ব্যয় ইউনিট, সুতরাং এর থেকে আরও ভাল কিছু পাওয়ার চেষ্টা করার কোনও মানে নেই। অবশ্যই, সন্ধানটি আসলে একের পরিবর্তে 7,388,383 টি সারি দেয়, একই সংখ্যক কী লুপআপের কারণ হয়ে।

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

এই বিশেষ প্রশ্নের জন্য, আমি দ্রুত জিজ্ঞাসা পরিকল্পনাটি সংকলনের সময় অপ্টিমাইজারের দ্বারা প্রস্তাবিত সূচকটি বাস্তবায়নের বিষয়ে চিন্তা করব:

/*
The Query Processor estimates that implementing the following index could improve
the query cost by 98.8091%.

WARNING: This is only an estimate, and the Query Processor is making this 
recommendation based solely upon analysis of this specific query.
It has not considered the resulting index size, or its workload-wide impact,
including its impact on INSERT, UPDATE, DELETE performance.
These factors should be taken into account before creating this index.
*/
CREATE NONCLUSTERED INDEX [<Name of Missing Index>]
ON [dbo].[PDetail] ([ClientID],[PostedDate])
INCLUDE ([Amount]);

সূচকটি একটি ON PartitionSchemeName (PostedDate)ধারা সহ বিভাজনযুক্ত করা উচিত, তবে মূল বক্তব্যটি হ'ল একটি স্পষ্টত-সর্বোত্তম ডেটা অ্যাক্সেসের পথ সরবরাহ করা অপ্টিমাইজারকে OPTIMIZE FOR UNKNOWNস্থানীয় ভেরিয়েবলগুলি ব্যবহার করার মতো ইঙ্গিত বা পুরানো ফ্যাশনের কাজগুলি না করে , খারাপ পরিকল্পনা পছন্দগুলি এড়াতে সহায়তা করে ।

উন্নত সূচকের সাথে, Amountকলামটি পুনরুদ্ধার করার জন্য কী চেহারাটি মুছে ফেলা হবে, ক্যোয়ারী প্রসেসর এখনও ডায়নামিক পার্টিশন নির্মূল করতে পারে এবং নির্দিষ্ট ClientIDএবং তারিখের সীমা সন্ধানের জন্য ব্যবহার করতে পারে ।


কাশ আমি দুটি উত্তর সঠিক হিসাবে চিহ্নিত করতে পারতাম, তবে আবারও অতিরিক্ত তথ্যের জন্য ধন্যবাদ - খুব শিক্ষণীয়।
থমাস

1
আমি এই পোস্ট করার পরে বেশ কয়েক বছর হয়ে গেছে ... তবে আমি আপনাকে জানাতে চেয়েছিলাম। আমি এখনও সমস্ত হতাশার সময় "অসম্পূর্ণভাবে বোঝা" শব্দটি ব্যবহার করি এবং আমি যখন করি তখন আমি সবসময় পল হোয়াইটের কথা ভাবি। আমাকে প্রতিবার চকচকে করে তোলে।
থমাস

0

আমার ঠিক একই সমস্যা ছিল যেখানে একটি সঞ্চিত প্রক্রিয়া ধীরে ধীরে হয়ে যায়, OPTIMIZE FOR UNKNOWNএবং RECOMPILEক্যোয়ারী ইঙ্গিতগুলি স্বচ্ছলতা সমাধান করে এবং কার্যকর করার সময়টিকে গতিময় করে তোলে। তবে, নিম্নলিখিত দুটি পদ্ধতি সঞ্চিত পদ্ধতির ownিলেownাকে প্রভাবিত করে না: (i) পুনরায় ব্যবহার করে ক্যাশে সাফ করা (ii)। সুতরাং, ঠিক যেমনটি আপনি বলেছেন, এটি সত্যই পরামিতি ছিল না iff

ট্রেস পতাকা 2389 এবং 2390 পাশাপাশি সহায়তা করে না। কেবলমাত্র পরিসংখ্যান আপডেট করে ( EXEC sp_updatestats) এটি আমার জন্য করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.