আপডেটের কর্মক্ষমতা যেখানে কোনও ডেটা পরিবর্তন হয় না


31

যদি আমার কাছে একটি UPDATEবিবৃতি থাকে যা আসলে কোনও ডেটা পরিবর্তন করে না (কারণ ডেটা ইতিমধ্যে আপডেট অবস্থায় রয়েছে)। WHEREআপডেটটি রোধ করার জন্য ক্লজটিতে একটি চেক রেখে কোনও পারফরম্যান্স সুবিধা রয়েছে কি ?

উদাহরণস্বরূপ, নিম্নলিখিত আপডেটের 1 থেকে 2 তারিখের মধ্যে প্রয়োগের গতির মধ্যে কোনও পার্থক্য থাকবে:

CREATE TABLE MyTable (ID int PRIMARY KEY, Value int);
INSERT INTO MyTable (ID, Value)
VALUES
    (1, 1),
    (2, 2),
    (3, 3);

-- UPDATE 1
UPDATE MyTable
SET
    Value = 2
WHERE
    ID = 2
    AND Value <> 2;
SELECT @@ROWCOUNT;

-- UPDATE 2
UPDATE MyTable
SET
    Value = 2
WHERE
    ID = 2;
SELECT @@ROWCOUNT;

DROP TABLE MyTable;

আমি জিজ্ঞাসার কারণটি হ'ল অপরিবর্তিত সারিটি অন্তর্ভুক্ত করার জন্য আমার সারি গণনা প্রয়োজন তাই আইডি উপস্থিত না থাকলে একটি সন্নিবেশ করা উচিত কিনা তা আমি জানি। যেমন আমি আপডেট 2 ফর্মটি ব্যবহার করেছি। যদি আপডেট 1 ফর্মটি ব্যবহার করে কোনও পারফরম্যান্স সুবিধা থাকে তবে আমার কীভাবে কোনও প্রয়োজন সারি গণনাটি পাওয়া সম্ভব?


Sqlperformance.com/2012/10/t-sql-queries/conditional-updates দেখুন (যদিও আমি সেখানে কোনও মান পরিবর্তন করি না এমন মামলায় প্রোফাইল করি নি)।
অ্যারন বারট্রান্ড

উত্তর:


24

আমার যদি একটি আপডেটের বিবৃতি থাকে যা আসলে কোনও ডেটা পরিবর্তন করে না (কারণ ডেটা ইতিমধ্যে আপডেট হওয়া অবস্থায় রয়েছে), আপডেটটি রোধ করার জন্য যেখানে ধারাটি রয়েছে সেখানে একটি চেক স্থাপনে কোনও কার্যকারিতা সুবিধা রয়েছে কি?

আপডেটের 1 এর কারণে সামান্য পারফরম্যান্সের পার্থক্য থাকায় অবশ্যই তা থাকতে পারে :

  • আসলে কোনও সারি আপডেট না করে (তাই ডিস্কে লেখার জন্য কিছুই নয়, এমনকি লগের সর্বনিম্ন কার্যকলাপও নয়) এবং
  • প্রকৃত আপডেট করার জন্য যা প্রয়োজন তার চেয়ে কম সীমাবদ্ধ লকগুলি বাইরে নিয়ে যাওয়া (সুতরাং সমঝোতার জন্য ভাল) ( দয়া করে শেষের দিকে আপডেট বিভাগটি দেখুন )

তবে, তারতম্যের মধ্যে কতটুকু পরিমাণ আছে তা আপনার সিস্টেমে আপনার স্কিমা, এবং ডেটা এবং সিস্টেম লোড দিয়ে পরিমাপ করা দরকার। আপডেট না হওয়া আপডেটের আপডেটের উপর কতগুলি প্রভাব রয়েছে তার মধ্যে অনেকগুলি কারণ রয়েছে:

  • টেবিলে বিতর্ক করার পরিমাণ আপডেট করা হচ্ছে
  • সারি সংখ্যা আপডেট করা হচ্ছে
  • যদি টেবিলটিতে আপডেটের ট্রিগার থাকে তবে আপডেট করা হয় (প্রশ্নের উপর একটি মন্তব্যে মার্ক দ্বারা উল্লিখিত)। আপনি যদি নির্বাহ করেন UPDATE TableName SET Field1 = Field1, তবে একটি আপডেট ট্রিগার গুলি চালায় এবং নির্দেশ করে যে ক্ষেত্রটি আপডেট হয়েছিল (আপনি যদি আপডেট () বা COLUMNS_UPDATED ফাংশন ব্যবহার করে পরীক্ষা করেন ) এবং উভয় INSERTEDএবং DELETEDসারণীতে ক্ষেত্র একই মান।

এছাড়াও, নীচের সারসংক্ষেপ বিভাগটি পল হোয়াইটের নিবন্ধ, অ-আপডেটিং আপডেটগুলির প্রভাব (যা তার উত্তর সম্পর্কে একটি মন্তব্যে @ স্প্যাগেটিডবা উল্লেখ করেছেন) তে পাওয়া যায়:

এসকিউএল সার্ভারে আপডেট আপডেট অপারেশন প্রক্রিয়াকরণ করার সময় অপ্রয়োজনীয় লগিং বা পৃষ্ঠা ফ্লাশিং এড়ানোর জন্য বেশ কয়েকটি অপ্টিমাইজেশন রয়েছে যা স্থির ডাটাবেসে কোনও পরিবর্তন ঘটায় না।

  • একটি ক্লাস্টার টেবিলের আপডেটগুলি আপডেট না করে সাধারণত অতিরিক্ত লগিং এবং পৃষ্ঠা ফ্লাশিং এড়ানো হয়, যদি না ক্লাস্টার কী তৈরির (একটি অংশ) কলাম আপডেট অপারেশন দ্বারা প্রভাবিত না হয়।
  • যদি ক্লাস্টারের কীটির কোনও অংশ একই মানকে 'আপডেট' করা হয় তবে অপারেশনটি লগ হয় যেমন তথ্য বদলে গিয়েছিল এবং প্রভাবিত পৃষ্ঠাগুলি বাফার পুলটিতে নোংরা হিসাবে চিহ্নিত হয়েছে। এটি আপডেট-এর-পরে-সন্নিবেশকরণ ক্রিয়াকলাপে রূপান্তরিত করার ফলাফল।
  • হিপ টেবিলগুলি ক্লাস্টারযুক্ত টেবিলগুলির মতোই আচরণ করে, কেবলমাত্র কোনও অতিরিক্ত লগিং বা পৃষ্ঠা ফ্লাশিংয়ের জন্য একটি ক্লাস্টার কী না থাকলে। এটি এখনও অবধি রয়ে গেছে যেখানে নন-ক্লাস্টারযুক্ত প্রাথমিক কীটি স্তূপে উপস্থিত রয়েছে। কোনও স্তূপে আপডেট না করা আপডেটগুলি সাধারণত অতিরিক্ত লগিং এবং ফ্লাশিং এড়ান (তবে নীচে দেখুন)।
  • হ্যাপ এবং ক্লাস্টারযুক্ত টেবিল উভয়ই সারি অতিরিক্ত লগিং এবং ফ্লাশিংয়ের শিকার হবে যেখানে 'এসইটি কলাম_নাম = কলাম_নাম' ব্যতীত অন্য কোনও সিনট্যাক্স ব্যবহার করে 8000 বাইটের বেশি ডেটাযুক্ত একটি এলওবি কলাম একই মানতে আপডেট করা হবে।
  • কেবলমাত্র একটি ডাটাবেসের মধ্যে উভয় ধরণের সারি সংস্করণ বিচ্ছিন্নকরণ স্তর সক্ষম করা অতিরিক্ত লগিং এবং ফ্লাশিংয়ের কারণ হয়। আপডেট লেনদেনের জন্য কার্যকরভাবে বিচ্ছিন্নতা স্তরটি নির্বিশেষে এটি ঘটে।

দয়া করে মনে রাখবেন (বিশেষ করে যদি আপনি পলের সম্পূর্ণ নিবন্ধটি দেখার জন্য লিঙ্কটি অনুসরণ না করেন), নিম্নলিখিত দুটি আইটেম:

  1. আপডেট না করা আপডেটগুলিতে এখনও কিছু লগ ক্রিয়াকলাপ রয়েছে যা দেখায় যে কোনও লেনদেন শুরু এবং শেষ হচ্ছে। এটি কেবলমাত্র কোনও ডেটা পরিবর্তন হয় না (এটি এখনও ভাল সঞ্চয়) is

  2. আমি উপরে উল্লিখিত হিসাবে, আপনি আপনার সিস্টেমে পরীক্ষা করা প্রয়োজন। পল যে একই গবেষণা ক্যোয়ারী ব্যবহার করছেন সেগুলি ব্যবহার করুন এবং দেখুন আপনি একই ফলাফল পান কিনা। নিবন্ধে যা দেখানো হয়েছে তার চেয়ে আমি আমার সিস্টেমে কিছুটা ভিন্ন ফলাফল দেখছি। এখনও কোনও নোংরা পৃষ্ঠাগুলি লেখা নেই, তবে আরও কিছু লগ ক্রিয়াকলাপ।


... অপরিবর্তিত সারিটি অন্তর্ভুক্ত করার জন্য আমার সারি গণনা প্রয়োজন তাই আইডি উপস্থিত না থাকলে একটি সন্নিবেশ করা উচিত কিনা তা আমি জানি। ... আমার কি একরকম প্রয়োজন সারি গণনা পাওয়া সম্ভব?

সরলতার সাথে আপনি যদি কেবল একটি একক সারি নিয়ে কাজ করে থাকেন তবে আপনি নিম্নলিখিতটি করতে পারেন:

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 লক / আনলক অপারেশনগুলির পরিমাণ। এটি দুর্দান্ত পারফরম্যান্সের গ্যারান্টি নয়, তবে অবশ্যই পরীক্ষার জন্য মূল্যবান :-)।


14

কিছুটা জুম করে বড় ছবিটি নিয়ে ভাবুন। বাস্তব বিশ্বে, আপনার আপডেট বিবৃতিটি কি সত্যিই এর মতো দেখতে চলেছে:

UPDATE MyTable
  SET Value = 2
WHERE
     ID = 2
     AND Value <> 2;

বা এটি কি এর মতো আরও দেখাবে:

UPDATE Customers
  SET AddressLine1 = '123 Main St',
      AddressLine2 = 'Apt 24',
      City = 'Chicago',
      State = 'IL',
      (and a couple dozen more fields)
WHERE
     ID = 2
     AND (AddressLine1 <> '123 Main St'
     OR AddressLine2 <> 'Apt 24'
     OR City <> 'Chicago'
     OR State <> 'IL'
      (and a couple dozen more fields))

কারণ বাস্তব বিশ্বে, টেবিলগুলিতে প্রচুর কলাম রয়েছে। এর অর্থ গতিশীল স্ট্রিংগুলি তৈরি করতে আপনাকে প্রচুর জটিল গতিশীল অ্যাপ যুক্তি তৈরি করতে হবে, বা আপনাকে প্রতিটি ক্ষেত্রের আগে এবং পরে সামগ্রীগুলি প্রতিবার নির্দিষ্ট করতে হবে।

যদি আপনি প্রতিটি টেবিলের জন্য এই আপডেট স্টেটমেন্টগুলি গতিশীলভাবে তৈরি করেন, কেবলমাত্র ক্ষেত্রগুলিতে আপডেট হয়ে যাচ্ছেন, আপনি কয়েক বছর আগে NHibernate প্যারামিটার আকারের সমস্যার অনুরূপ একটি প্ল্যান ক্যাশে দূষণের সমস্যাটিতে দ্রুত চালাতে পারেন । আরও খারাপ, আপনি যদি এসকিউএল সার্ভারে আপডেট স্টেটমেন্টগুলি তৈরি করেন (সঞ্চিত পদ্ধতিগুলির মতো), তবে আপনি মূল্যবান সিপিইউ চক্র জ্বালিয়ে ফেলবেন কারণ এসকিউএল সার্ভার স্কেলগুলি একসাথে স্ট্রাইটিংয়ে ভয়ঙ্করভাবে দক্ষ নয়।

এই জটিলতার কারণে, আপনি আপডেটগুলি করছেন বলে সাধারণত এই জাতীয় সারি-সারি, ফিল্ড-বাই-ফিল্ড তুলনা করা বুদ্ধিমান হয় না। পরিবর্তে সেট-ভিত্তিক অপারেশনগুলি ভাবেন।


1
আমার আসল বিশ্বের উদাহরণটি এটির মতো সহজ তবে প্রচুর পরিমাণে ডাকা হয়। আমার অনুমানটি পিক সময়ে প্রতি 15 মিনিটে একবার। আমি ভাবছিলাম যে এসকিউএল সার্ভারের প্রয়োজন নেই তখন ডিস্কে না লেখার পক্ষে যথেষ্ট চালাক is
মার্টিন ব্রাউন

3

আপনি সারিগুলি এড়িয়ে যাওয়ার ক্ষেত্রে এমন পারফরম্যান্স লাভ দেখতে পেয়েছেন যা কেবল তখনই আপডেট করার প্রয়োজন হয় না যখন সারিগুলির সংখ্যা বড় হয় (কম লগিং, ডিস্কে লিখতে কম নোংরা পৃষ্ঠাগুলি)।

আপনার ক্ষেত্রে যেমন একক সারি আপডেটগুলি নিয়ে কাজ করা হয় তখন পারফরম্যান্সের পার্থক্য সম্পূর্ণ নগণ্য। যদি সকল ক্ষেত্রে সারিগুলি আপডেট করা আপনার পক্ষে সহজ করে তোলে তবে এটি করুন।

এই বিষয়ে আরও তথ্যের জন্য দেখুন পল হোয়াইটের নন আপডেটিং আপডেটগুলি


3

আপনি আপডেটটি একত্রিত করতে পারেন এবং একটি বিবৃতিতে sertোকাতে পারেন। এসকিউএল সার্ভারে, আপনি আপডেট উভয়টি করার জন্য একটি মার্জ স্টেটমেন্ট ব্যবহার করতে পারেন এবং যদি খুঁজে না পাওয়া যায় তবে সন্নিবেশ করতে পারেন। মাইএসকিউএল-এর জন্য, আপনি কী কী আপডেটের জন্য ডিপলিকেট ইনসার্ট ব্যবহার করতে পারেন ।


1

সমস্ত ক্ষেত্রের মানগুলি পরীক্ষা করার পরিবর্তে, আপনি যে কলামগুলিতে আগ্রহী সেগুলি ব্যবহার করে আপনি কি হ্যাশ মান পাবেন না তারপরে সারণির সারিটির বিপরীতে সংরক্ষিত হ্যাশের সাথে তুলনা করুন?

IF EXISTS (Select 1 from Table where ID =@ID AND HashValue=Sha256(column1+column2))
GOTO EXIT
ELSE
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.