এসকিউএল সার্ভার 2012 এবং 2016 স্ট্যান্ডার্ড: যদি আমি কোনও পরামিতির মানের উপর নির্ভর করে কোডের দুটি শাখার মধ্যে একটি নির্বাহ করতে স্টোরেজ পদ্ধতিতে যদি-অন্য যুক্তি রাখি তবে ইঞ্জিনটি সর্বশেষ সংস্করণটি ক্যাশে করে?
না, এটি সমস্ত সংস্করণকে ক্যাশে করে । বা বরং, এটি ভেরিয়েবলগুলিতে পাসের সাথে সংকলিত সমস্ত পাথ অন্বেষণকৃত একটি সংস্করণকে ক্যাশে করে ।
স্ট্যাক ওভারফ্লো ডাটাবেস ব্যবহার করে এখানে একটি দ্রুত ডেমো রয়েছে।
একটি সূচক তৈরি করুন:
CREATE INDEX ix_yourmom ON dbo.Users (Reputation) INCLUDE (Id, DisplayName);
GO
ব্রাঙ্কড কোডে কোনও সূচককে নির্দেশ করে এমন একটি সূচক ইঙ্গিত সহ একটি সঞ্চিত পদ্ধতি তৈরি করুন।
CREATE OR ALTER PROCEDURE dbo.YourMom (@Reputation INT)
AS
BEGIN
IF @Reputation = 1
BEGIN
SELECT u.Id, u.DisplayName, u.Reputation
FROM dbo.Users AS u WITH (INDEX = PK_Users_Id)
WHERE u.Reputation = @Reputation;
END;
IF @Reputation > 1
BEGIN
SELECT u.Id, u.DisplayName, u.Reputation
FROM dbo.Users AS u WITH (INDEX = ix_yourdad)
WHERE u.Reputation = @Reputation;
END;
END;
আমি যদি সঞ্চিত = 1 সন্ধানের জন্য সঞ্চিত সংগ্রহটি কার্যকর করি তবে আমি একটি ত্রুটি পেয়েছি।
EXEC dbo.YourMom @Reputation = 1;
এমএসজি 308, স্তর 16, রাজ্য 1, আপনার মম প্রক্রিয়া, লাইন 14 [ব্যাচ স্টার্ট লাইন 32] সূচী 'ix_yourdad' টেবিলের 'dbo.User' (FROM ধারাটিতে বর্ণিত) বিদ্যমান নেই।
আমরা যদি সূচকের নামটি ঠিক করি এবং ক্যোয়ারীটি আবার চালিত করি, তবে ক্যাশেড প্ল্যানটি এরকম দেখাচ্ছে:
ভিতরে, এক্সএমএল এর @Reputation
ভেরিয়েবলের দুটি উল্লেখ থাকবে ।
<ColumnReference Column="@Reputation" ParameterDataType="int" ParameterCompiledValue="(1)" />
কিছুটা সহজ পরীক্ষা হ'ল সঞ্চিত প্রকল্পের জন্য একটি আনুমানিক পরিকল্পনা নেওয়া। আপনি অপটিমাইজার উভয় পাথ অন্বেষণ করতে পারেন:
এবং যদি নিম্নলিখিত নির্বাহের উপর, প্যারামিটারটির মান পরিবর্তন হয়, তবে এটি কি পুনরায় সংকলন করে এবং সঞ্চিত পদ্ধতিটিকে পুনরায় ক্যাশে করবে, কারণ কোডের একটি পৃথক শাখা কার্যকর করা উচিত? (এই প্রশ্নের সংকলনটি বেশ ব্যয়বহুল)) আপনাকে ধন্যবাদ।
না, এটি প্রথম সংকলনের রানটাইম মান ধরে রাখবে।
আমরা যদি অন্যর সাথে পুনরায় কার্যকর করি @Reputation
:
EXEC dbo.YourMom @Reputation = 2;
থেকে প্রকৃত পরিকল্পনা :
<ColumnReference Column="@Reputation" ParameterDataType="int" ParameterCompiledValue="(1)" ParameterRuntimeValue="(2)" />
আমাদের কাছে এখনও 1 টি সংকলিত মান রয়েছে তবে এখন রানটাইম 2 এর মান।
পরিকল্পনার ক্যাশে, যা আপনি আমার সংস্থার বিকাশের মতো একটি নিখরচায় সরঞ্জাম দিয়ে যাচাই করতে পারেন, sp_BlitzCache :
সঞ্চিত পদ্ধতিটি দু'বার কল করা হয়েছে এবং এতে প্রতিটি বিবৃতি একবার কল করা হয়েছে।
তাহলে কি আমরা আছি? সঞ্চিত পদ্ধতিতে উভয় প্রশ্নের জন্য একটি ক্যাশেড পরিকল্পনা।
আপনি যদি এই ধরণের ব্রাঞ্চযুক্ত যুক্তি চান তবে আপনাকে সাব-স্টোরেজ পদ্ধতিতে কল করতে হবে:
CREATE OR ALTER PROCEDURE dbo.YourMom (@Reputation INT)
AS
BEGIN
IF @Reputation = 1
BEGIN
EXEC dbo.Reputation1Query;
END;
IF @Reputation > 1
BEGIN
EXEC dbo.ReputationGreaterThan1Query;
END;
END;
বা গতিশীল এসকিউএল:
DECLARE @sql NVARCHAR(MAX) = N''
SET @sql +=
N'
SELECT u.Id, u.DisplayName, u.Reputation
FROM dbo.Users AS u '
IF @Reputation = 1
BEGIN
SET @sql += N' (INDEX = PK_Users_Id)
WHERE u.Reputation = @Reputation;'
END;
IF @Reputation > 1
BEGIN
SET @sql += ' WITH (INDEX = ix_yourmom)
WHERE u.Reputation = @Reputation;'
END;
EXEC sys.sp_executesql @sql;
আশাকরি এটা সাহায্য করবে!