পরিকল্পনাটি একটি এসকিউএল সার্ভার ২০০৮ আর 2 আরটিএম ইনস্ট্যান্সে তৈরি করা হয়েছিল (10.50.1600 বিল্ড করুন)। আপনার ইনস্টল করা উচিত সার্ভিস প্যাক 3 (10.50.6000 তৈরি করুন) এবং সর্বশেষতম প্যাচগুলি এটি (বর্তমান) সর্বশেষতম বিল্ড 10.50.6542 এ আনতে হবে followed সুরক্ষা, বাগ সংশোধন এবং নতুন বৈশিষ্ট্য সহ বিভিন্ন কারণে এটি গুরুত্বপূর্ণ।
প্যারামিটার এম্বেডিং অপটিমাইজেশন
বর্তমান প্রশ্নের সাথে সম্পর্কিত, এসকিউএল সার্ভার ২০০৮ আর 2 আরটিএম এর জন্য প্যারামিটার এম্বেডিং অপ্টিমাইজেশন (পিইও) সমর্থন করে না OPTION (RECOMPILE)
। এই মুহুর্তে, আপনি মূল সুবিধাগুলির মধ্যে একটি অনুধাবন না করে পুনঃনির্মাণের মূল্য প্রদান করছেন।
যখন পিইও উপলব্ধ থাকে, এসকিউএল সার্ভার স্থানীয় ভেরিয়েবল এবং প্যারামিটারগুলিতে সংরক্ষিত আক্ষরিক মানগুলি সরাসরি ক্যোয়ারী পরিকল্পনায় ব্যবহার করতে পারে। এটি নাটকীয় সরলীকরণ এবং পারফরম্যান্স বৃদ্ধি হতে পারে। আমার নিবন্ধে সে সম্পর্কে আরও তথ্য রয়েছে, প্যারামিটার স্নিফিং, এম্বেডিং এবং পুনঃসংযোগ বিকল্পগুলি ।
হ্যাশ, বাছাই এবং এক্সচেঞ্জ স্পিলস
এসকিউএল সার্ভার ২০১২ বা তারপরে কোয়েরিটি সংকলিত হয়েছিল তখন এগুলি কেবল কার্যকরকরণ পরিকল্পনাগুলিতে প্রদর্শিত হয়। পূর্ববর্তী সংস্করণগুলিতে, ক্যোয়ারী প্রোফাইলার বা বর্ধিত ইভেন্টগুলি ব্যবহার করে চালিত হওয়ার সময় আমাদের স্পিলের জন্য নজরদারি করতে হয়েছিল। স্পিল সবসময় শারীরিক I / O থেকে (এবং থেকে) অবিচ্ছিন্ন স্টোরেজ ব্যাকিং টেম্পডিবিতে আসে ফলাফল দেয়, যার কার্যকর কার্যকারিতা হতে পারে, বিশেষত যদি বড় হয়, বা I / O পাথ চাপে থাকে।
আপনার এক্সিকিউশন প্ল্যানে, দুটি হ্যাশ ম্যাচ (সমষ্টি) অপারেটর রয়েছে। হ্যাশ টেবিলের জন্য সংরক্ষিত মেমরিটি আউটপুট সারিগুলির অনুমানের উপর ভিত্তি করে (অন্য কথায়, এটি রানটাইমের সময় পাওয়া গ্রুপগুলির সংখ্যার সাথে আনুপাতিক)। প্রদত্ত মেমরিটি কার্যকর হওয়া শুরু হওয়ার ঠিক আগে স্থির করা হয় এবং কার্যকরকরণের সময় উদাহরণস্বরূপ কতটা মুক্ত মেমরি থাকে তা নির্বিশেষে বাড়তে পারে না। সরবরাহিত পরিকল্পনায়, উভয় হ্যাশ ম্যাচ (সমষ্টি) অপারেটরগুলি অপটিমাইজারের প্রত্যাশার চেয়ে বেশি সারি তৈরি করে এবং তাই রানটাইমটিতে টেম্পডবি করার জন্য একটি প্রস্রাবের সম্মুখীন হতে পারে ।
পরিকল্পনায় একটি হ্যাশ ম্যাচ (ইনার জয়েন) অপারেটরও রয়েছে। হ্যাশ টেবিলের জন্য সংরক্ষিত মেমরিটি প্রোব পার্শ্ব ইনপুট সারিগুলির অনুমানের ভিত্তিতে । অনুসন্ধানের ইনপুটটি 847,399 টি সারি অনুমান করে, তবে 1,223,636 রান সময়টিতে সম্মুখীন হয়। এই অতিরিক্তটি হ্যাশ ছড়িয়ে পড়ার কারণ হতে পারে।
অপ্রয়োজনীয় সমষ্টি
নোড 8-এ হ্যাশ ম্যাচ (সমষ্টি) একটি গ্রুপিং ক্রিয়াকলাপ সম্পাদন করে (Assortment_Id, CustomAttrID)
তবে ইনপুট সারিগুলি আউটপুট সারিগুলির সমান:
এটি কলাম সংমিশ্রণটি একটি কী (তাই গোষ্ঠীকরণটি শব্দার্থগতভাবে অপ্রয়োজনীয়) পরামর্শ দেয়। অপ্রয়োজনীয় সমষ্টি সম্পাদনের ব্যয় হ্যাশ পার্টিশনিং এক্সচেঞ্জগুলিতে দুইবার 1.4 মিলিয়ন সারি পাস করার প্রয়োজনীয়তা দ্বারা বৃদ্ধি করা হয়েছে (উভয় পক্ষের সমান্তরালতা অপারেটর)।
জবাব দেওয়া কলামগুলি বিভিন্ন টেবিল থেকে আসে, এই স্বতন্ত্রতা তথ্যটি অপ্টিমাইজারের সাথে যোগাযোগ করা স্বাভাবিকের চেয়ে বেশি কঠিন, তাই এটি অপ্রয়োজনীয় গ্রুপিং অপারেশন এবং অপ্রয়োজনীয় এক্সচেঞ্জগুলি এড়াতে পারে।
অপর্যাপ্ত থ্রেড বিতরণ
জো ওবিশের উত্তরে উল্লিখিত হিসাবে , নোড 14 এ এক্সচেঞ্জ থ্রেডগুলির মধ্যে সারি বিতরণ করতে হ্যাশ বিভাজন ব্যবহার করে। দুর্ভাগ্যক্রমে, সংখ্যার কম সংখ্যক সারি এবং উপলব্ধ সিডিউলারের অর্থ তিনটি সারি একক থ্রেডে শেষ। আপাতদৃষ্টিতে সমান্তরাল পরিকল্পনাটি ক্রমিকভাবে (সমান্তরাল ওভারহেড সহ) নোড 9 এ এক্সচেঞ্জের অবধি চলে।
নোড 13 এ ডিসট্রিন্ট সাজান্ট কেটে আপনি এটিকে (রাউন্ড-রবিন বা ব্রডকাস্ট পার্টিশন অর্জনের জন্য) সম্বোধন করতে পারেন that এটি করার সহজতম উপায় হ'ল #temp
টেবিলে একটি ক্লাস্টার্ড প্রাথমিক কী তৈরি করা এবং টেবিলটি লোড করার সময় স্বতন্ত্র ক্রিয়াকলাপ সম্পাদন করা:
CREATE TABLE #Temp
(
id integer NOT NULL PRIMARY KEY CLUSTERED
);
INSERT #Temp
(
id
)
SELECT DISTINCT
CAV.id
FROM @customAttrValIds AS CAV
WHERE
CAV.id IS NOT NULL;
অস্থায়ী টেবিলের পরিসংখ্যান ক্যাশে
ব্যবহার সত্ত্বেও OPTION (RECOMPILE)
, এসকিউএল সার্ভার এখনও অস্থায়ী টেবিল অবজেক্ট এবং প্রক্রিয়া কলগুলির মধ্যে সম্পর্কিত সম্পর্কিত পরিসংখ্যানকে ক্যাশে করতে পারে । এটি সাধারণত একটি স্বাগত কর্মক্ষমতা অপ্টিমাইজেশন, তবে অস্থায়ী টেবিলটি সংলগ্ন প্রক্রিয়া কলগুলিতে একই পরিমাণের ডেটা দ্বারা পপুলেশন করা থাকলে পুনরায় সংযুক্ত পরিকল্পনাটি ভুল পরিসংখ্যানের উপর ভিত্তি করে তৈরি হতে পারে (একটি পূর্ববর্তী মৃত্যুদন্ড কার্যকর করা)) এটি আমার নিবন্ধগুলিতে বিশদভাবে রয়েছে, সঞ্চিত পদ্ধতিতে অস্থায়ী টেবিলগুলি এবং অস্থায়ী টেবিল ক্যাশে ব্যাখ্যা করা হয় ।
এটি এড়াতে অস্থায়ী টেবিলটি জনপ্রিয় হওয়ার পরে এবং এটি কোনও ক্যোরিতে রেফারেন্স দেওয়ার আগে OPTION (RECOMPILE)
একটি স্পষ্ট সঙ্গে একসাথে ব্যবহার করুন UPDATE STATISTICS #TempTable
।
পুনরায় লেখার প্রশ্ন
এই অংশটি ধরে নিয়েছে যে #Temp
টেবিল তৈরির পরিবর্তনগুলি ইতিমধ্যে করা হয়েছে।
সম্ভাব্য হ্যাশ স্পিলের ব্যয় এবং অতিরিক্ত কাজ (এবং আশেপাশের এক্সচেঞ্জ) দেওয়া, এটি নোড 10 এ সেটটি বাস্তবায়নের জন্য অর্থ দিতে পারে:
CREATE TABLE #Temp2
(
CustomAttrID integer NOT NULL,
Assortment_Id integer NOT NULL,
);
INSERT #Temp2
(
Assortment_Id,
CustomAttrID
)
SELECT
ACAV.Assortment_Id,
CAV.CustomAttrID
FROM #temp AS T
JOIN dbo.CustomAttributeValues AS CAV
ON CAV.Id = T.id
JOIN dbo.AssortmentCustomAttributeValues AS ACAV
ON T.id = ACAV.CustomAttributeValue_Id;
ALTER TABLE #Temp2
ADD CONSTRAINT PK_#Temp2_Assortment_Id_CustomAttrID
PRIMARY KEY CLUSTERED (Assortment_Id, CustomAttrID);
PRIMARY KEY
একটি পৃথক ধাপে যোগ করা হয় সূচক বিল্ড নিশ্চিত করার সঠিক cardinality তথ্য হয়েছে, এবং ইস্যু ক্যাশে অস্থায়ী টেবিল পরিসংখ্যান এড়ানো।
উদাহরণস্বরূপ পর্যাপ্ত মেমরি উপলব্ধ থাকলে এই ধাতবকরণ মেমরির ( টেম্পিডবি আই / ও এড়িয়ে চলা ) হওয়ার সম্ভাবনা রয়েছে। আপনি এসকিউএল সার্ভার ২০১২ (এসপি 1 সিই 10 / এসপি 2 সিই 1 বা তারপরে) আপগ্রেড হওয়ার পরে এটি আরও বেশি সম্ভাবনা রয়েছে যা এগার লেখার আচরণকে উন্নত করেছে ।
এই ক্রিয়াটি মধ্যবর্তী সেটে অনুকূলকরণের সঠিক কার্ডিনালিটির তথ্য দেয়, এটি পরিসংখ্যান তৈরি করতে দেয় এবং আমাদের (Assortment_Id, CustomAttrID)
কী হিসাবে ঘোষণা করতে দেয় ।
জনসংখ্যার পরিকল্পনাগুলি #Temp2
দেখতে এইরকম হওয়া উচিত (ক্লাস্টারড ইনডেক্স স্ক্যানটি নোট করুন #Temp
, কোনও বিচ্ছিন্ন বাছাই করা নেই, এবং এক্সচেঞ্জটি এখন রাউন্ড-রবিন সারি পার্টিশন ব্যবহার করে):
এই সেটটি উপলভ্য হওয়ার সাথে সাথে চূড়ান্ত ক্যোয়ারীটি হয়ে যায়:
SELECT
A.Id,
A.AssortmentId
FROM
(
SELECT
T.Assortment_Id
FROM #Temp2 AS T
GROUP BY
T.Assortment_Id
HAVING
COUNT_BIG(DISTINCT T.CustomAttrID) = @dist_ca_id
) AS DT
JOIN dbo.Assortments AS A
ON A.Id = DT.Assortment_Id
WHERE
A.AssortmentType = @asType
OPTION (RECOMPILE);
আমরা ম্যানুয়ালি COUNT_BIG(DISTINCT...
এটিকে একটি সাধারণ হিসাবে পুনরায় লিখতে পারি COUNT_BIG(*)
, তবে নতুন কী তথ্য সহ, অপ্টিমাইজারটি আমাদের জন্য এটি করে:
চূড়ান্ত পরিকল্পনাটি আমার কাছে অ্যাক্সেস নেই এমন ডেটা সম্পর্কিত পরিসংখ্যান সম্পর্কিত তথ্যের উপর নির্ভর করে একটি লুপ / হ্যাশ / মার্জ জোড় ব্যবহার করতে পারে। অন্য একটি ছোট নোট: আমি ধরে নিয়েছি যে এর মতো একটি সূচকও CREATE [UNIQUE?] NONCLUSTERED INDEX IX_ ON dbo.Assortments (AssortmentType, Id, AssortmentId);
বিদ্যমান।
যাইহোক, চূড়ান্ত পরিকল্পনাগুলি সম্পর্কে গুরুত্বপূর্ণ বিষয়টি হল অনুমানগুলি আরও ভাল হওয়া উচিত এবং গ্রুপিং ক্রিয়াকলাপগুলির জটিল ক্রমটি একটি একক স্ট্রিম এগ্রিগ্রেটে হ্রাস করা হয়েছে (যার জন্য মেমরির প্রয়োজন হয় না এবং তাই ডিস্কে ছড়িয়ে দিতে পারে না)।
এটি বলা শক্ত যে অতিরিক্ত অস্থায়ী টেবিলের সাথে এই ক্ষেত্রে পারফরম্যান্স আসলে আরও ভাল হবে , তবে সময়ের সাথে সাথে ডেটা ভলিউম এবং বিতরণে পরিবর্তনের জন্য অনুমানগুলি এবং পরিকল্পনার পছন্দগুলি আরও বেশি স্থিতিস্থাপক হবে। এটি আজ একটি ছোট পারফরম্যান্স বৃদ্ধির চেয়ে দীর্ঘমেয়াদে আরও মূল্যবান হতে পারে। যাই হোক না কেন, আপনার চূড়ান্ত সিদ্ধান্তটি কোনটি ভিত্তিতে ভিত্তি করে তা এখন আপনার কাছে আরও অনেক তথ্য রয়েছে।
#temp
সৃষ্টি এবং ব্যবহার কার্যকারিতার জন্য সমস্যা হবে, লাভ নয়। আপনি কেবলমাত্র একবার ব্যবহার করার জন্য একটি আনডেক্সড টেবিলটিতে সঞ্চয় করছেন। এটি সম্পূর্ণরূপে অপসারণ করার চেষ্টা করুন (এবং সম্ভবত এটিin (select id from #temp)
একটিexists
উপশাস্ত্রে পরিবর্তন করুন