উত্তর:
এটি নির্ভর করে কলামটি কীভাবে সংজ্ঞায়িত করে তার উপর নির্ভর করে। একটি PERSISTED
গণিত কলাম গণনা করা হবে এবং তারপরে সারণীর অভ্যন্তরে ডেটা হিসাবে সংরক্ষণ করা হবে। আপনি যদি কলামটি PERSISTED
এটি হিসাবে সংজ্ঞায়িত না করেন তবে আপনার ক্যোয়ারীটি চালিত হলে এটি গণনা করা হবে।
একটি দুর্দান্ত ব্যাখ্যা এবং প্রমাণের জন্য দয়া করে হারুনের উত্তর দেখুন ।
পিনাল ডেভও এটিকে বিশদভাবে বর্ণনা করে এবং তার সিরিজের স্টোরেজের প্রমাণ দেখায়:
এটি নিজের পক্ষে প্রমাণ করা খুব সহজ। আমরা একটি কম্পিউটেড কলাম দিয়ে একটি সারণী তৈরি করতে পারি যা স্কেলার ব্যবহারকারী-সংজ্ঞায়িত ফাংশন ব্যবহার করে এবং তারপরে একটি আপডেটের আগে এবং পরে পরিকল্পনা এবং ফাংশন পরিসংখ্যানগুলি পরীক্ষা করে নির্বাচন করতে পারি এবং কখন এক্সিকিউশনটি রেকর্ড হয়।
ধরা যাক আমাদের এই ফাংশনটি রয়েছে:
CREATE FUNCTION dbo.mask(@x varchar(32))
RETURNS varchar(32) WITH SCHEMABINDING
AS
BEGIN
RETURN (SELECT 'XX' + SUBSTRING(@x, 3, LEN(@x)-4) + 'XXXX');
END
GO
এবং এই টেবিল:
CREATE TABLE dbo.Floobs
(
FloobID int IDENTITY(1,1),
Name varchar(32),
MaskedName AS CONVERT(varchar(32), dbo.mask(Name)),
CONSTRAINT pk_Floobs PRIMARY KEY(FloobID),
CONSTRAINT ck_Name CHECK (LEN(Name)>=8)
);
GO
sys.dm_exec_function_stats
একটি সন্নিবেশের আগে এবং পরে এবং তারপরে একটি নির্বাচনের পরে (এসকিউএল সার্ভার 2016 এবং অ্যাজুরে এসকিউএল ডেটাবেসগুলিতে নতুন ) পরীক্ষা করা যাক :
SELECT o.name, s.execution_count
FROM sys.dm_exec_function_stats AS s
INNER JOIN sys.objects AS o
ON o.[object_id] = s.[object_id]
WHERE s.database_id = DB_ID();
INSERT dbo.Floobs(Name) VALUES('FrankieC');
SELECT o.name, s.execution_count
FROM sys.dm_exec_function_stats AS s
INNER JOIN sys.objects AS o
ON o.[object_id] = s.[object_id]
WHERE s.database_id = DB_ID();
SELECT * FROM dbo.Floobs;
SELECT o.name, s.execution_count
FROM sys.dm_exec_function_stats AS s
INNER JOIN sys.objects AS o
ON o.[object_id] = s.[object_id]
WHERE s.database_id = DB_ID();
আমি sertোকাতে কোনও ফাংশন কল দেখতে পাচ্ছি না, কেবলমাত্র নির্বাচন করুন on
এখন, টেবিলগুলি ফেলে দিন এবং এটি করুন, এবার কলামটি এতে পরিবর্তন করুন PERSISTED
:
DROP TABLE dbo.Floobs;
GO
DROP FUNCTION dbo.mask;
GO
...
MaskedName AS CONVERT(varchar(32), dbo.mask(Name)) PERSISTED,
...
এবং আমি বিপরীতটি ঘটতে দেখছি: আমি সন্নিবেশটিতে একটি সম্পাদনা পেয়েছি, তবে নির্বাচিতটিতে নেই।
এসকিউএল সার্ভারের ব্যবহারের মতো আধুনিক সংস্করণ নেই sys.dm_exec_function_stats
? কোনও উদ্বেগ নয়, এটি কার্যকর করার পরিকল্পনায়ও ধরা পড়ে ।
অ-স্থিত সংস্করণটির জন্য, আমরা কেবলমাত্র ফাংশনটি নির্বাচিতটিতে উল্লেখ করতে পারি:
যখন অবিচ্ছিন্ন সংস্করণটি কেবল সন্নিবেশ করানোর ক্ষেত্রে গণনাটি দেখায়:
এখন, মার্টিন একটি মন্তব্যে একটি দুর্দান্ত বক্তব্য তুলে ধরেছেন : এটি সর্বদা সত্য হবে না। আসুন এমন একটি সূচি তৈরি করুন যা স্থির গণিত কলামটি কভার করে না, এবং সেই সূচিটি ব্যবহার করে এমন একটি ক্যোয়ারী চালাও এবং দেখুন যে বিদ্যমান উপস্থিত ডাটা থেকে ডেটা পাওয়া যায় বা রানটাইমের সময় ডেটা গণনা করে (ড্রপ এবং পুনরায় তৈরি ফাংশন) এবং টেবিল এখানে):
CREATE INDEX x ON dbo.Floobs(Name);
GO
INSERT dbo.Floobs(name)
SELECT LEFT(name, 32)
FROM sys.all_columns
WHERE LEN(name) >= 8;
এখন, আমরা সূচি ব্যবহার করে এমন একটি কোয়েরি চালাব (আসলে এটি নির্দিষ্ট ক্ষেত্রে যেমন নির্ধারিত ক্ষেত্রে ছাড়াই ডিফল্টরূপে সূচকটি ব্যবহার করে):
SELECT * FROM dbo.Floobs WITH (INDEX(x))
WHERE Name LIKE 'S%';
আমি ফাংশন পরিসংখ্যানগুলিতে অতিরিক্ত ফাঁসি দেখছি এবং পরিকল্পনাটি মিথ্যা নয়:
সুতরাং, উত্তরটি এটি নির্ভর করে । এই ক্ষেত্রে, এসকিউএল সার্ভার ভেবেছিল যে লকআপগুলি সম্পাদন করার চেয়ে মানগুলি পুনরায় গণনা করা সস্তা হবে। এটি বিভিন্ন কারণের কারণে পরিবর্তিত হতে পারে, সুতরাং এটির উপর নির্ভর করবেন না। এবং এটি কোনও দিকনির্দেশেই ঘটতে পারে কোনও ব্যবহারকারী-সংজ্ঞায়িত ফাংশন ব্যবহৃত হয় কি না; আমি কেবল এটি এখানে ব্যবহার করেছি কারণ এটি চিত্রিত করা এত সহজ করে তুলেছে।
এই প্রশ্নের উত্তর সত্যই "এটি নির্ভর করে"। আমি সবেমাত্র একটি উদাহরণ জুড়ে চলেছি যেখানে এসকিউএল সার্ভার স্থির গণিত কলামে সূচকটি ব্যবহার করছে তবে এটি এখনও ফাংশনটি সম্পাদন করছে, যেন মানগুলি কখনই শুরু হয় না। এটি কলামের ডেটা ধরণের ( nvarchar(37)
) বা সম্ভবত টেবিলের আকার (প্রায় 7 মিলিয়ন সারি) সহ করতে পারে, তবে এসকিউএল সার্ভার persisted
কীওয়ার্ডটিকে উপেক্ষা করার সিদ্ধান্ত নিয়েছে , এটি নির্দিষ্ট উদাহরণে উপস্থিত হয়।
এই ক্ষেত্রে, টেবিলের প্রাথমিক কীটি হ'ল ট্রানজেকশনআইডি যা একটি গণিত এবং অবিচল কলামও। এক্সিকিউশন প্ল্যান একটি সূচক স্ক্যান তৈরি করছে এবং কেবল million মিলিয়ন সারি সহ একটি টেবিলের মধ্যে এই সাধারণ ক্যোয়ারিটি চালাতে ২-৩ মিনিটের বেশি সময় নেয় কারণ ফাংশনটি প্রতিটি সারিতে আবার চালানো হয় এবং মানগুলি স্থির থাকে না বলে মনে হয় সূচক।