একই মান সহ একটি সারি আপডেট করা কি আসলে সারিটি আপডেট করে?


28

আমার একটি পারফরম্যান্স সম্পর্কিত প্রশ্ন আছে। ধরা যাক, আমার প্রথম নাম মাইকেল সহ একটি ব্যবহারকারী আছে। নিম্নলিখিত কোয়েরি নিন:

UPDATE users
SET first_name = 'Michael'
WHERE users.id = 123

কোয়েরিটি কি একই মানটিতে আপডেট হওয়া সত্ত্বেও আপডেটটি সম্পাদন করবে? যদি তা হয় তবে আমি কীভাবে এটি ঘটতে রোধ করব?


1
আপনি কেন একটি বিবৃতি কার্যকর করবেন এবং একই সাথে এটি কার্যকর করবেন না বলে আশা করবেন?
ম্যাক্স ভার্নন

@ ম্যাক্স ভার্নন রুবি অন রেলস এর ওআরএম রেকর্ডটি আপডেট করে না তাই পোস্টগ্র্রেএসকিউএল একই কাজ করে থাকলে আমি কৌতূহলী ছিলাম।
OneSneakyMofo

1
আমি পরামর্শ দিচ্ছি যে রুবেল অন রেলগুলি এটি করছে কিনা, সারিটির কোনও আপডেট দরকার কিনা তা দেখার জন্য এটি সম্ভবত প্রথমে একটি নির্বাচন করছে।
ম্যাক্স ভার্নন

উত্তর:


35

পোস্টগ্রিসের এমভিসিসি মডেলের কারণে এবং এসকিউএল-এর নিয়ম অনুসারে, একটি প্রতিটি সারির UPDATEজন্য একটি নতুন সারি সংস্করণ লিখেছে যা ধারাটিতে বাদ নেই ।WHERE

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

সূচিপত্রগুলি এবং টোস্টেড কলামগুলি যেখানে জড়িত কলামগুলির কোনওই পরিবর্তিত হয় না একইরকম থাকতে পারে না, তবে কোনও আপডেট হওয়া সারির ক্ষেত্রে এটি সত্য। সম্পর্কিত:

এ জাতীয় খালি আপডেটগুলি বাদ দেওয়া প্রায় সর্বদা একটি ভাল ধারণা (যখন এটির আসল সুযোগ থাকে তখন)। আপনি আপনার প্রশ্নে একটি সারণী সংজ্ঞা প্রদান করেন নি (যা সর্বদা একটি ভাল ধারণা)। আমাদের ধরে নিতে first_nameহবে নুল হতে পারে (যা "প্রথম নাম" এর জন্য অবাক হওয়ার মতো হবে না), সুতরাং কোয়েরিতে নুল-নিরাপদ তুলনাটি ব্যবহার করতে হবে :

UPDATE users
SET    first_name = 'Michael'
WHERE  id = 123
AND   first_name IS DISTINCT FROM 'Michael';

যদি first_name IS NULLআপডেটের আগে, কেবলমাত্র একটি পরীক্ষা first_name <> 'Michael'NUL এর মূল্যায়ন করবে এবং যেমন আপডেট থেকে সারি বাদ দেয়। লুক্কায়িত ত্রুটি। যদি কলামটি সংজ্ঞায়িত করা হয়NOT NULL তবে সাধারণ সাম্যতা চেক ব্যবহার করুন, যদিও এটি কিছুটা সস্তা।

সম্পর্কিত:


1
Indexes entries and TOASTed columns where none of the involved columns are changed can stay the sameতবে কি তাদের সারিটির নতুন অবস্থানে নির্দেশ করতে আপডেট করতে হবে না?
ডিভিটান

1
@ ডিটিজিকি: এইচওটি আপডেটের সাথে নয়, যেখানে সূচকটি পুরানো অবস্থানটির দিকে নির্দেশ করতে পারে এবং লাইভ টিপল পেতে হ্যাপ চেইনগুলি অতিক্রম করতে হবে। আমি উপরের আরও ব্যাখ্যায় লিঙ্কগুলি যুক্ত করেছি।
এরউইন ব্র্যান্ডসটেটার

1
নতুন টিউপল লেখার জন্য এমভিসিসি একটি নূরের আপডেটের জন্য কল করবে?
jbodyman

@ জবেরিম্যান: আমি নিশ্চিত বুঝতে পারছি না। যেভাবেই হোক, দয়া করে আপনার প্রশ্নটিকে নতুন প্রশ্ন হিসাবে জিজ্ঞাসা করুন । আপনি প্রসঙ্গের জন্য সর্বদা এটির সাথে লিঙ্ক করতে পারেন। এবং ফিরে লিঙ্ক করতে আপনি এখানে একটি মন্তব্য করতে পারেন (এবং আমার দৃষ্টি আকর্ষণ করুন)।
এরউইন ব্র্যান্ডস্টেটার

2
@ জবেরিম্যান: প্রকল্পটি কেন এভাবে চলছিল তার কারণগুলি আমি আসলে জানি না । এটি অনেক আগে প্রতিষ্ঠিত হয়েছিল। তবে আমি ধরে নিই যে সাম্যের জন্য প্রতিটি সারি পরীক্ষা করা অযথা ব্যয়বহুল হবে এবং অপরিবর্তিত সারিগুলির জন্য আলাদা কোড-পাথ থাকবে। লেনদেন-আইডি হ্যান্ডলিং আরও জটিল হবে - বিশেষ কেসিংয়ের জন্য rollback, স্ন্যাপশট হ্যান্ডলিং, লক ম্যানেজমেন্ট, ওয়াল, কী নয় ...
এরউইন ব্র্যান্ডসেটেটার

4

ওআরএম-র রবি অন রেলের অফার স্থগিত মৃত্যুদন্ড যা রেকর্ডকে পরিবর্তিত (বা না) হিসাবে চিহ্নিত করে এবং তারপরে যখন প্রয়োজন হয় বা ডাকা হয়, তারপরে পরিবর্তনটি ডাটাবেসে জমা দিন।

পোস্টগ্রিসকিউএল একটি ওআরএম নয় এমন একটি ডাটাবেস। এটির কার্যকারিতা হ্রাস পেয়েছে যদি আপনার জিজ্ঞাসায় আপডেট হওয়া মানের মতো কোনও নতুন মান একই ছিল কিনা তা পরীক্ষা করতে সময় লাগলে।

এটি নতুন মান হিসাবে একই কিনা তা নির্বিশেষে এটি মান আপডেট করবে।

আপনি যদি এটি প্রতিরোধ করতে চান তবে আপনি ম্যাক্স ভার্নন তার উত্তরে প্রস্তাবিত কোড ব্যবহার করতে পারেন।


2

আপনি কেবল এই whereধারাটিতে যুক্ত করতে পারেন :

UPDATE users
SET first_name = 'Michael'
WHERE users.id = 123
    AND (first_name <> 'Michael' OR first_name IS NULL);

যদি first_nameহিসাবে সংজ্ঞায়িত করা হয় NOT NULL, OR first_name IS NULLঅংশটি সরানো যেতে পারে।

অবস্থা:

(first_name <> 'Michael' OR first_name IS NULL)

আরও (যেমন ইরউনের উত্তরে) আরও মার্জিতভাবে রচনা করা যেতে পারে:

first_name IS DISTINCT FROM 'Michael'

কলামটি নুল হতে পারে কিনা তা জানেন না, এটি একটি স্নিগ্ধ বাগটি প্রবর্তন করতে পারে।
এরউইন ব্র্যান্ডসটেটার

1
@ এরউইন ব্র্যান্ডস্টেটর আমি উত্তরটি আপডেট করছি - তারপরে আমি মন্তব্য এবং আপনার উত্তরটি দেখেছি!
ypercubeᵀᴹ

সম্পাদনা করার জন্য ধন্যবাদ, @ সাইপারকিউ - এবং NULL@ মেরিন সম্পর্কে মন্তব্য করার জন্য
ম্যাক্স ভার্নন

1

দেখুন একটি ডাটাবেস দৃষ্টিকোণ থেকে

আপনার প্রশ্নের উত্তর হ্যাঁ। আপডেটটি স্থান নেবে। ডাটাবেসটি পূর্ববর্তী মানটি পরীক্ষা করে না, এটি কেবলমাত্র নতুন মান সেট করে।

স্মৃতিতে যেমন ঘটে থাকে (এবং কোনও প্রতিশ্রুতি জারি করার পরে এটি কেবল ডেটাফাইলে লেখা হবে) পারফরম্যান্স কোনও সমস্যা হবে না।

একটি ORM দৃষ্টিকোণ থেকে

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

এটি বিভিন্ন আচরণ ব্যাখ্যা করতে পারে।

এখন, কোনও কার্গো শিপকে 3 ডি প্রিন্টারের সাথে তুলনা করা যাক। কার্গো শিপ ব্যবহার করে আপনি 3 ডি প্রিন্টার প্রেরণ করতে পারবেন না এর অর্থ এই নয় যে তাদের মধ্যে কোনও ধরণের তুলনা থাকতে পারে।

উপভোগ করুন!

আমি আশা করি এটি কিছু ধারণা পরিষ্কার করেছে।


4
পারফরমেন্স হয় এবং সমস্যা। প্রতিটি আপডেট ডিস্কে লিখতে হবে (লগ এবং টেবিল)।
ypercubeᵀᴹ

এটি আপনার ব্যবহার করা আসল আরডিবিএমএসের উপর নির্ভর করবে। তবে তাদের বেশিরভাগই প্রতিটি একক আপডেট প্রতিশ্রুতিবদ্ধ না, কেবল মেমরির মধ্যে রয়েছে সর্বশেষ প্রত্যাবর্তিত ব্লক। আপনি কখনই ডেটাবেসে একক সারিটি পড়েন বা লিখেন না। আপনি ব্লকগুলি পড়েন / লেখেন এবং এটিকে একই জায়গায় নতুন ব্লক স্থাপন না করা পর্যন্ত এগুলি মেমোরিতে রাখেন। স্মৃতিতে থাকাকালীন, প্রতিটি সারির প্রতিটি পরিবর্তনই ডিস্কে লিখিত হবে না, তবে কেবল "ব্লগের বিষয়বস্তু যখন" ডাটাবেস লেখক "প্রক্রিয়া সেই মেমরি ব্লকটিকে একটি ডেটা ফাইলে ফেলে দেওয়ার জন্য সংকেত দেওয়া হয়। সুতরাং, না ... কোনও সমস্যা নয় যদি না আপনার অ্যাপ্লিকেশনটি দীর্ঘ সময়ের জন্য অবরুদ্ধটিকে অবরুদ্ধ করে না রাখে।
সিলভারিয়ন

1
প্রশ্ন পোস্টগ্রিস সম্পর্কে, কোনও স্বেচ্ছাসেবক ডিবিএমএস সম্পর্কে নয়। এবং আপডেটগুলি সকলকে একে একে লিখতে হবে না, ডাটাবেসের প্রতিটি লেখাই লগতে লিখতে হবে। যদি অবিচ্ছিন্ন স্টোরেজে কোনও পরিবর্তন লিখিত না হয়, তবে ডিবিএমএস কীভাবে একটি সিস্টেম ক্র্যাশ থেকে বেঁচে থাকবে?
ypercubeᵀᴹ

হ্যাঁ, এটি লগগুলিতে, স্মৃতি থেকে এবং চেকপয়েন্টগুলির সময় লেখায়। আপনার যদি না খুব সহজেই প্রচুর পরিমাণে সমসাময়িক ব্যবহারকারী থাকে তবে এগুলিতে মোটেই সমস্যা হওয়া উচিত নয়। লগগুলি পাশাপাশি ব্যাচে লেখা হয়। আমি মনে করি আমরা সার্ভারগুলি নিয়ে কথা বলছি। আপনি যদি 5400 আরপিএম এইচডিডি সহ একটি ল্যাপটপে পোস্টগ্রিস ডাটাবেসের কথা বলছেন তবে হ্যাঁ ... আপনার সর্বদা পারফরম্যান্সের সমস্যা থাকবে। সুতরাং, চূড়ান্ত উত্তরটি প্রথমটি হবে ... এটি অনেক কিছুর উপর নির্ভর করে।
সিলভারিয়ন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.