আমার যদি একটি আপডেটের বিবৃতি থাকে যা আসলে কোনও ডেটা পরিবর্তন করে না (কারণ ডেটা ইতিমধ্যে আপডেট হওয়া অবস্থায় রয়েছে), আপডেটটি রোধ করার জন্য যেখানে ধারাটি রয়েছে সেখানে একটি চেক স্থাপনে কোনও কার্যকারিতা সুবিধা রয়েছে কি?
আপডেটের 1 এর কারণে সামান্য পারফরম্যান্সের পার্থক্য থাকায় অবশ্যই তা থাকতে পারে :
- আসলে কোনও সারি আপডেট না করে (তাই ডিস্কে লেখার জন্য কিছুই নয়, এমনকি লগের সর্বনিম্ন কার্যকলাপও নয়) এবং
- প্রকৃত আপডেট করার জন্য যা প্রয়োজন তার চেয়ে কম সীমাবদ্ধ লকগুলি বাইরে নিয়ে যাওয়া (সুতরাং সমঝোতার জন্য ভাল) ( দয়া করে শেষের দিকে আপডেট বিভাগটি দেখুন )
তবে, তারতম্যের মধ্যে কতটুকু পরিমাণ আছে তা আপনার সিস্টেমে আপনার স্কিমা, এবং ডেটা এবং সিস্টেম লোড দিয়ে পরিমাপ করা দরকার। আপডেট না হওয়া আপডেটের আপডেটের উপর কতগুলি প্রভাব রয়েছে তার মধ্যে অনেকগুলি কারণ রয়েছে:
- টেবিলে বিতর্ক করার পরিমাণ আপডেট করা হচ্ছে
- সারি সংখ্যা আপডেট করা হচ্ছে
- যদি টেবিলটিতে আপডেটের ট্রিগার থাকে তবে আপডেট করা হয় (প্রশ্নের উপর একটি মন্তব্যে মার্ক দ্বারা উল্লিখিত)। আপনি যদি নির্বাহ করেন
UPDATE TableName SET Field1 = Field1
, তবে একটি আপডেট ট্রিগার গুলি চালায় এবং নির্দেশ করে যে ক্ষেত্রটি আপডেট হয়েছিল (আপনি যদি আপডেট () বা COLUMNS_UPDATED ফাংশন ব্যবহার করে পরীক্ষা করেন ) এবং উভয় INSERTED
এবং DELETED
সারণীতে ক্ষেত্র একই মান।
এছাড়াও, নীচের সারসংক্ষেপ বিভাগটি পল হোয়াইটের নিবন্ধ, অ-আপডেটিং আপডেটগুলির প্রভাব (যা তার উত্তর সম্পর্কে একটি মন্তব্যে @ স্প্যাগেটিডবা উল্লেখ করেছেন) তে পাওয়া যায়:
এসকিউএল সার্ভারে আপডেট আপডেট অপারেশন প্রক্রিয়াকরণ করার সময় অপ্রয়োজনীয় লগিং বা পৃষ্ঠা ফ্লাশিং এড়ানোর জন্য বেশ কয়েকটি অপ্টিমাইজেশন রয়েছে যা স্থির ডাটাবেসে কোনও পরিবর্তন ঘটায় না।
- একটি ক্লাস্টার টেবিলের আপডেটগুলি আপডেট না করে সাধারণত অতিরিক্ত লগিং এবং পৃষ্ঠা ফ্লাশিং এড়ানো হয়, যদি না ক্লাস্টার কী তৈরির (একটি অংশ) কলাম আপডেট অপারেশন দ্বারা প্রভাবিত না হয়।
- যদি ক্লাস্টারের কীটির কোনও অংশ একই মানকে 'আপডেট' করা হয় তবে অপারেশনটি লগ হয় যেমন তথ্য বদলে গিয়েছিল এবং প্রভাবিত পৃষ্ঠাগুলি বাফার পুলটিতে নোংরা হিসাবে চিহ্নিত হয়েছে। এটি আপডেট-এর-পরে-সন্নিবেশকরণ ক্রিয়াকলাপে রূপান্তরিত করার ফলাফল।
- হিপ টেবিলগুলি ক্লাস্টারযুক্ত টেবিলগুলির মতোই আচরণ করে, কেবলমাত্র কোনও অতিরিক্ত লগিং বা পৃষ্ঠা ফ্লাশিংয়ের জন্য একটি ক্লাস্টার কী না থাকলে। এটি এখনও অবধি রয়ে গেছে যেখানে নন-ক্লাস্টারযুক্ত প্রাথমিক কীটি স্তূপে উপস্থিত রয়েছে। কোনও স্তূপে আপডেট না করা আপডেটগুলি সাধারণত অতিরিক্ত লগিং এবং ফ্লাশিং এড়ান (তবে নীচে দেখুন)।
- হ্যাপ এবং ক্লাস্টারযুক্ত টেবিল উভয়ই সারি অতিরিক্ত লগিং এবং ফ্লাশিংয়ের শিকার হবে যেখানে 'এসইটি কলাম_নাম = কলাম_নাম' ব্যতীত অন্য কোনও সিনট্যাক্স ব্যবহার করে 8000 বাইটের বেশি ডেটাযুক্ত একটি এলওবি কলাম একই মানতে আপডেট করা হবে।
- কেবলমাত্র একটি ডাটাবেসের মধ্যে উভয় ধরণের সারি সংস্করণ বিচ্ছিন্নকরণ স্তর সক্ষম করা অতিরিক্ত লগিং এবং ফ্লাশিংয়ের কারণ হয়। আপডেট লেনদেনের জন্য কার্যকরভাবে বিচ্ছিন্নতা স্তরটি নির্বিশেষে এটি ঘটে।
দয়া করে মনে রাখবেন (বিশেষ করে যদি আপনি পলের সম্পূর্ণ নিবন্ধটি দেখার জন্য লিঙ্কটি অনুসরণ না করেন), নিম্নলিখিত দুটি আইটেম:
আপডেট না করা আপডেটগুলিতে এখনও কিছু লগ ক্রিয়াকলাপ রয়েছে যা দেখায় যে কোনও লেনদেন শুরু এবং শেষ হচ্ছে। এটি কেবলমাত্র কোনও ডেটা পরিবর্তন হয় না (এটি এখনও ভাল সঞ্চয়) is
আমি উপরে উল্লিখিত হিসাবে, আপনি আপনার সিস্টেমে পরীক্ষা করা প্রয়োজন। পল যে একই গবেষণা ক্যোয়ারী ব্যবহার করছেন সেগুলি ব্যবহার করুন এবং দেখুন আপনি একই ফলাফল পান কিনা। নিবন্ধে যা দেখানো হয়েছে তার চেয়ে আমি আমার সিস্টেমে কিছুটা ভিন্ন ফলাফল দেখছি। এখনও কোনও নোংরা পৃষ্ঠাগুলি লেখা নেই, তবে আরও কিছু লগ ক্রিয়াকলাপ।
... অপরিবর্তিত সারিটি অন্তর্ভুক্ত করার জন্য আমার সারি গণনা প্রয়োজন তাই আইডি উপস্থিত না থাকলে একটি সন্নিবেশ করা উচিত কিনা তা আমি জানি। ... আমার কি একরকম প্রয়োজন সারি গণনা পাওয়া সম্ভব?
সরলতার সাথে আপনি যদি কেবল একটি একক সারি নিয়ে কাজ করে থাকেন তবে আপনি নিম্নলিখিতটি করতে পারেন:
UPDATE MyTable
SET Value = 2
WHERE ID = 2
AND Value <> 2;
IF (@@ROWCOUNT = 0)
BEGIN
IF (NOT EXISTS(
SELECT *
FROM MyTable
WHERE ID = 2 -- or Value = 2 depending on the scenario
)
)
BEGIN
INSERT INTO MyTable (ID, Value) -- or leave out ID if it is an IDENTITY
VALUES (2, 2);
END;
END;
একাধিক সারিগুলির জন্য, আপনি এই OUTPUT
ধারাটি ব্যবহার করে সিদ্ধান্ত গ্রহণের জন্য প্রয়োজনীয় তথ্য পেতে পারেন । সারিগুলি ঠিক কী আপডেট হয়েছিল তা ক্যাপচার করে, আপনি সারিগুলি আপডেট না করার বিপরীতে যে সারি বিদ্যমান নেই তা আপডেট করার প্রয়োজন নেই তবে আপডেটের প্রয়োজন নেই তার মধ্যে পার্থক্য জানতে আপনি আইটেমগুলি সঙ্কুচিত করতে পারেন।
আমি নীচের উত্তরে প্রাথমিক প্রয়োগটি দেখাই:
এক্সএমএল প্যারামিটার ব্যবহার করে একাধিক ডেটা সংরক্ষণ করার সময় মার্জ কোয়েরি ব্যবহার কীভাবে এড়ানো যায়?
এই উত্তরে প্রদর্শিত পদ্ধতিটি এখনও বিদ্যমান সারিগুলিকে ফিল্টার করে না এবং আপডেট করার প্রয়োজন নেই। এই অংশটি যুক্ত করা যেতে পারে তবে আপনাকে প্রথমে আপনাকে যেখানে আপনার একত্রে ডেটাসেটটি মিশ্রিত করা হচ্ছে তা ঠিক দেখাতে হবে MyTable
। তারা কি কোনও অস্থায়ী টেবিল থেকে আসছে? একটি টেবিল-মূল্যবান প্যারামিটার (টিভিপি)?
আপডেট 1:
অবশেষে আমি কিছু পরীক্ষা করতে সক্ষম হয়েছি এবং লেনদেন লগ এবং লকিংয়ের বিষয়ে আমি এখানে যা পেয়েছি তা এখানে। প্রথমত, টেবিলের জন্য স্কিমা:
CREATE TABLE [dbo].[Test]
(
[ID] [int] NOT NULL CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED,
[StringField] [varchar](500) NULL
);
এরপরে, ক্ষেত্রটি ইতিমধ্যে তার মানটিতে ক্ষেত্রটি আপডেট করে:
UPDATE rt
SET rt.StringField = '04CF508B-B78E-4264-B9EE-E87DC4AD237A'
FROM dbo.Test rt
WHERE rt.ID = 4082117
ফলাফল:
-- Transaction Log (2 entries):
Operation
----------------------------
LOP_BEGIN_XACT
LOP_COMMIT_XACT
-- SQL Profiler (3 Lock:Acquired events):
Mode Type
--------------------------------------
8 - IX 5 - OBJECT
8 - IX 6 - PAGE
5 - X 7 - KEY
অবশেষে, মানটি পরিবর্তন না হওয়ার কারণে যে পরীক্ষাটি আপডেটটি ফিল্টার করে:
UPDATE rt
SET rt.StringField = '04CF508B-B78E-4264-B9EE-E87DC4AD237A'
FROM dbo.Test rt
WHERE rt.ID = 4082117
AND rt.StringField <> '04CF508B-B78E-4264-B9EE-E87DC4AD237A';
ফলাফল:
-- Transaction Log (0 entries):
Operation
----------------------------
-- SQL Profiler (3 Lock:Acquired events):
Mode Type
--------------------------------------
8 - IX 5 - OBJECT
7 - IU 6 - PAGE
4 - U 7 - KEY
যেমন আপনি দেখতে পাচ্ছেন, লেনদেনের সূচনা এবং সমাপ্তি চিহ্নিত দুটি এন্ট্রির বিপরীতে সারিটি ফিল্টার করার সময় লেনদেন লগকে কিছুই লেখা হয় না। এবং যদিও এটি সত্য যে এই দুটি এন্ট্রি প্রায় কিছুই নয়, তারা এখনও কিছু।
এছাড়াও, পরিবর্তন করা হয়নি এমন সারিগুলিকে ফিল্টার করার সময় PAGE এবং KEY সংস্থানগুলিতে লক করা কম সীমাবদ্ধ। যদি অন্য কোনও প্রক্রিয়া এই টেবিলের সাথে ইন্টারঅ্যাক্ট না করে থাকে তবে এটি সম্ভবত একটি নন-ইস্যু (তবে এটি সম্ভবত কতটা সম্ভব?) মনে রাখবেন যে লিঙ্কযুক্ত যে কোনও একটিতে (এবং আমার পরীক্ষাটিও) পরীক্ষিত পরীক্ষাগুলি স্পষ্টতই ধরে নিয়েছে যে টেস্টের অংশ না হওয়ায় টেবিলে কোনও বিতর্ক নেই। বলছেন যে আপডেট না করা আপডেটগুলি এত হালকা ওজনযুক্ত যে ফিল্টারিংয়ের জন্য এটি পরিশোধের প্রয়োজন হয় না কারণ পরীক্ষা শূন্যে কমবেশি টেস্টিং চালানো হয় salt তবে উত্পাদনে, এই টেবিলটি সম্ভবত বিচ্ছিন্ন নয়। অবশ্যই, এটি খুব ভালভাবেই হতে পারে যে সামান্য কিছু লগিং এবং আরও সীমাবদ্ধ লকগুলি কম দক্ষতার মধ্যে অনুবাদ করে না। এই তথ্যের উত্তর দেওয়ার জন্য তথ্যের সবচেয়ে নির্ভরযোগ্য উত্স? SQL সার্ভার. বিশেষ করে:আপনার এসকিউএল সার্ভার এটি আপনাকে দেখাবে যে আপনার সিস্টেমের জন্য কোন পদ্ধতিটি ভাল :-)।
আপডেট 2:
যে ক্রিয়াকলাপে নতুন মানটি বর্তমান মানের সমান (যেমন কোনও আপডেট নেই) যে অপারেশনগুলিতে নতুন মান পৃথক এবং আপডেট প্রয়োজনীয়, তার পরে নিম্নলিখিত প্যাটার্নটি আরও ভাল প্রমাণিত হতে পারে, বিশেষত যদি টেবিলে অনেক বিতর্ক আছে। ধারণাটি হ'ল SELECT
বর্তমান মান পেতে প্রথমে একটি সাধারণ কাজ করা do যদি আপনি কোনও মূল্য না পান তবে আপনার কাছে উত্তরটি সম্পর্কিত INSERT
। আপনার যদি মান থাকে তবে আপনি একটি সাধারণ কাজ করতে পারেন IF
এবং UPDATE
কেবল প্রয়োজন হলেই ইস্যু করতে পারেন।
DECLARE @CurrentValue VARCHAR(500) = NULL,
@NewValue VARCHAR(500) = '04CF508B-B78E-4264-B9EE-E87DC4AD237A',
@ID INT = 4082117;
SELECT @CurrentValue = rt.StringField
FROM dbo.Test rt
WHERE rt.ID = @ID;
IF (@CurrentValue IS NULL) -- if NULL is valid, use @@ROWCOUNT = 0
BEGIN
-- row does not exist
INSERT INTO dbo.Test (ID, StringField)
VALUES (@ID, @NewValue);
END;
ELSE
BEGIN
-- row exists, so check value to see if it is different
IF (@CurrentValue <> @NewValue)
BEGIN
-- value is different, so do the update
UPDATE rt
SET rt.StringField = @NewValue
FROM dbo.Test rt
WHERE rt.ID = @ID;
END;
END;
ফলাফল:
-- Transaction Log (0 entries):
Operation
----------------------------
-- SQL Profiler (2 Lock:Acquired events):
Mode Type
--------------------------------------
6 - IS 5 - OBJECT
6 - IS 6 - PAGE
সুতরাং 3 এর পরিবর্তে মাত্র 2 টি লক অধিগ্রহণ করা হয়েছে এবং এই দুটি লকই ইন্টেন্ট শেয়ার্ড, ইনটেন্ট এক্সক্লুসিভ বা ইনটেন্ট আপডেট ( লক সামঞ্জস্যতা ) নয়। একত্রিত প্রতিটি লকটিও মুক্তি পাবে এ বিষয়টি মাথায় রেখে, প্রতিটি লকটি সত্যই 2 টি অপারেশন, সুতরাং এই নতুন পদ্ধতিটি মূলত প্রস্তাবিত পদ্ধতিতে 6 টি অপারেশনের পরিবর্তে মোট 4 টি অপারেশন। বিবেচনা করে এই অপারেশনটি প্রতি 15 এমএসে একবার চালাচ্ছে (প্রায়, ওপি দ্বারা বর্ণিত), যা প্রতি সেকেন্ডে প্রায় 66 বার। সুতরাং আসল প্রস্তাবটির পরিমাণ প্রতি সেকেন্ডে 396 লক / আনলক অপারেশন, যখন এই নতুন পদ্ধতিটি এমনকি হালকা ওজন লকগুলির প্রতি সেকেন্ডে কেবল 264 লক / আনলক অপারেশনগুলির পরিমাণ। এটি দুর্দান্ত পারফরম্যান্সের গ্যারান্টি নয়, তবে অবশ্যই পরীক্ষার জন্য মূল্যবান :-)।