এসকিউএল সার্ভার - যদি সঞ্চিত প্রক্রিয়া এবং পরিকল্পনার ক্যাশে লজিক থাকে


15

এসকিউএল সার্ভার 2012 এবং 2016 স্ট্যান্ডার্ড:

যদি আমি if-elseকোনও প্যারামিটারের মানের উপর ভিত্তি করে কোডের দুটি শাখার মধ্যে একটি নির্বাহের জন্য একটি সঞ্চিত পদ্ধতিতে যুক্তি রাখি তবে ইঞ্জিনটি সর্বশেষ সংস্করণটি ক্যাশে করে?

এবং যদি নিম্নলিখিত নির্বাহের উপর, প্যারামিটারটির মান পরিবর্তন হয়, তবে এটি কি পুনরায় সংকলন করে এবং সংরক্ষণ করা পদ্ধতিটিকে পুনরায়-ক্যাশে করবে , যেহেতু কোডের একটি পৃথক শাখা কার্যকর করা উচিত? (এই প্রশ্নের সংকলনটি বেশ ব্যয়বহুল))

উত্তর:


27

এসকিউএল সার্ভার 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;

আশাকরি এটা সাহায্য করবে!

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