এটি আপনার টেবিলগুলির তথ্যগুলি, আপনার সূচীগুলিতে, উপর নির্ভর করে .... কার্যকর করার পরিকল্পনাগুলি / আইও + সময়ের পরিসংখ্যানগুলির তুলনা করতে সক্ষম হওয়া ছাড়া বলা শক্ত।
আমি যে পার্থক্যটি আশা করব তা হ'ল দুটি টেবিলের মধ্যবর্তী জিনের আগে অতিরিক্ত ফিল্টারিং। আমার উদাহরণে, আমি আমার টেবিলগুলি পুনরায় ব্যবহার করতে নির্বাচনগুলিতে আপডেটগুলি পরিবর্তন করেছি।
"অপ্টিমাইজেশন" সহ কার্যকরকরণ পরিকল্পনা
হত্যা পরিকল্পনা
আপনি পরিষ্কারভাবে একটি ফিল্টার অপারেশন ঘটতে দেখছেন, আমার পরীক্ষার ডেটাতে ফিল্টার আউট হয়েছে এমন কোনও রেকর্ড নেই এবং ফলস্বরূপ যেখানে কোনও উন্নতি হয়নি।
"অপ্টিমাইজেশন" ছাড়াই কার্যকর করার পরিকল্পনা
হত্যা পরিকল্পনা
ফিল্টারটি গেছে, যার অর্থ অপ্রয়োজনীয় রেকর্ডগুলি ফিল্টার করার জন্য আমাদের যোগদানের উপর নির্ভর করতে হবে।
অন্যান্য কারণ (গুলি)
কোয়েরিটি পরিবর্তনের আরেকটি কারণ / পরিণতি হতে পারে, ক্যোয়ারী পরিবর্তন করার সময় একটি নতুন এক্সিকিউশন প্ল্যান তৈরি করা হয়েছিল, যা দ্রুত হয়। এর উদাহরণ হ'ল ইঞ্জিনটি একটি পৃথক জোড় অপারেটর নির্বাচন করে তবে এটি এই মুহূর্তে অনুমান করা যায়।
সম্পাদনা করুন:
দুটি ক্যোয়ারী প্ল্যান পাওয়ার পরে স্পষ্ট করা:
কোয়েরিটি বড় টেবিল থেকে 550 এম সারিগুলি পড়ছে এবং সেগুলি ছাঁটাই করছে।
এর অর্থ হ'ল প্রিডিকেট হ'ল ফিল্টারিংয়ের বেশিরভাগ কাজ করছেন, অনুসন্ধানের পূর্বে নয়। ডেটা পড়া হচ্ছে ফলাফল, কিন্তু কম ফেরত আসছে।
এসকিএল সার্ভারকে আলাদা সূচক (ক্যোয়ারী পরিকল্পনা) ব্যবহার করা / একটি সূচি যুক্ত করা এটি সমাধান করতে পারে।
তাহলে কেন অনুকূলিত ক্যোয়ারিতে এই একই সমস্যা নেই?
কারণ সন্ধানের পরিবর্তে স্ক্যান সহ একটি আলাদা ক্যোয়ারী পরিকল্পনা ব্যবহৃত হয় plan
কোনও সন্ধান না করে, তবে কেবল 4 এম সারি নিয়ে কাজ করতে হবে।
পরবর্তী পার্থক্য
আপডেটের পার্থক্যটিকে উপেক্ষা করে (অনুকূলিত ক্যোয়ারিতে কিছুই আপডেট করা হচ্ছে না) অনুকূলিত ক্যোয়ারিতে একটি হ্যাশ ম্যাচ ব্যবহৃত হয়:
নেস্টেড লুপের পরিবর্তে অ-অনুকূলিতকরণে যোগ দিন:
একটি টেবিল ছোট এবং অন্যটি বড় হলে নেস্টেড লুপটি সেরা। যেহেতু তারা উভয়ই একই আকারের কাছাকাছি থাকায় আমি যুক্তি দিয়ে বলব যে হ্যাশ ম্যাচ এই ক্ষেত্রে ভাল পছন্দ।
সংক্ষিপ্ত বিবরণ
অপ্টিমাইজড কোয়েরি
অপ্টিমাইজড ক্যোয়ারির পরিকল্পনার সমান্তরালতা রয়েছে, একটি হ্যাশ ম্যাচ জয়েন ব্যবহার করা হয়েছে এবং এর জন্য কম রেসিডুয়াল আইও ফিল্টারিং করা দরকার। এটি মূল মানগুলি মুছে ফেলার জন্য একটি বিটম্যাপ ব্যবহার করে যা কোনও যোগদানের সারি তৈরি করতে পারে না। (এছাড়াও কিছুই আপডেট করা হচ্ছে না)
অ অপ্টিমাইজ ক্যোয়ারী
অ অনুকূল ক্যোয়ারী পরিকল্পনা, কোন parallellism রয়েছে নেস্টেড লুপ যোগদানের ব্যবহার করে এবং চাহিদা 550M রেকর্ড উপর ফিল্টারিং অবশিষ্ট আই না। (এছাড়াও আপডেটটি হচ্ছে)
অপ্টিমাইজড কোয়েরিটি উন্নত করতে আপনি কী করতে পারেন?
মূল কলাম তালিকায় প্রথম_নাম এবং শেষ নাম রাখাতে সূচকটি পরিবর্তন করা হচ্ছে:
INDEX IX_largeTableOfPeople_birth_date_first_name_last_name on dbo.largeTableOfPeople (জন্ম_ তারিখ, প্রথম নাম, সর্বশেষ_নাম) অন্তর্ভুক্ত (আইডি)
তবে ফাংশনগুলির ব্যবহার এবং এই টেবিলটি বড় হওয়ার কারণে এটি সর্বোত্তম সমাধান হতে পারে না।
- উন্নত পরিকল্পনাটি পাওয়ার জন্য পুনরায় সংকলন ব্যবহার করে পরিসংখ্যান আপডেট করা।
- অনুযায়ী OPTION যোগ করার পদ্ধতি
(HASH JOIN, MERGE JOIN)
প্রশ্নের
- ...
পরীক্ষার ডেটা + ক্যোরি ব্যবহার করা হয়েছে
CREATE TABLE #smallTableOfPeople(importantValue int, birthDate datetime2, first_name varchar(50),last_name varchar(50));
CREATE TABLE #largeTableOfPeople(importantValue int, birth_date datetime2, first_name varchar(50),last_name varchar(50));
set nocount on;
DECLARE @i int = 1
WHILE @i <= 1000
BEGIN
insert into #smallTableOfPeople (importantValue,birthDate,first_name,last_name)
VALUES(NULL, dateadd(mi,@i,'2018-01-18 11:05:29.067'),'Frodo','Baggins');
set @i += 1;
END
set nocount on;
DECLARE @j int = 1
WHILE @j <= 20000
BEGIN
insert into #largeTableOfPeople (importantValue,birth_Date,first_name,last_name)
VALUES(@j, dateadd(mi,@j,'2018-01-18 11:05:29.067'),'Frodo','Baggins');
set @j += 1;
END
SET STATISTICS IO, TIME ON;
SELECT smallTbl.importantValue , largeTbl.importantValue
FROM #smallTableOfPeople smallTbl
JOIN #largeTableOfPeople largeTbl
ON largeTbl.birth_date = smallTbl.birthDate
AND DIFFERENCE(RTRIM(LTRIM(smallTbl.last_name)),RTRIM(LTRIM(largeTbl.last_name))) = 4
AND DIFFERENCE(RTRIM(LTRIM(smallTbl.first_name)),RTRIM(LTRIM(largeTbl.first_name))) = 4
WHERE smallTbl.importantValue IS NULL
-- The following line is "the optimization"
AND LEFT(RTRIM(LTRIM(largeTbl.last_name)), 1) IN ('a','à','á','b','c','d','e','è','é','f','g','h','i','j','k','l','m','n','o','ô','ö','p','q','r','s','t','u','ü','v','w','x','y','z','æ','ä','ø','å');
SELECT smallTbl.importantValue , largeTbl.importantValue
FROM #smallTableOfPeople smallTbl
JOIN #largeTableOfPeople largeTbl
ON largeTbl.birth_date = smallTbl.birthDate
AND DIFFERENCE(RTRIM(LTRIM(smallTbl.last_name)),RTRIM(LTRIM(largeTbl.last_name))) = 4
AND DIFFERENCE(RTRIM(LTRIM(smallTbl.first_name)),RTRIM(LTRIM(largeTbl.first_name))) = 4
WHERE smallTbl.importantValue IS NULL
-- The following line is "the optimization"
--AND LEFT(RTRIM(LTRIM(largeTbl.last_name)), 1) IN ('a','à','á','b','c','d','e','è','é','f','g','h','i','j','k','l','m','n','o','ô','ö','p','q','r','s','t','u','ü','v','w','x','y','z','æ','ä','ø','å')
drop table #largeTableOfPeople;
drop table #smallTableOfPeople;
AND LEFT(TRIM(largeTbl.last_name), 1) BETWEEN 'a' AND 'z' COLLATE LATIN1_GENERAL_CI_AI
সমস্ত অক্ষর তালিকাভুক্ত করার প্রয়োজন নেই এবং পড়তে