PostgreSQL এ বাল্ক আপডেট পারফরম্যান্স অনুকূল করা


37

উবুন্টু 12.04-তে পিজি 9.1 ব্যবহার করা।

বর্তমানে আমাদের কোনও ডাটাবেসে আপডেটের স্টেটমেন্টের একটি বড় সেট চালাতে 24 ঘন্টা অবধি লাগে, যা ফর্মটির মধ্যে রয়েছে:

UPDATE table
SET field1 = constant1, field2 = constant2, ...
WHERE id = constid

(আমরা কেবল আইডি দ্বারা চিহ্নিত বস্তুর ক্ষেত্রগুলি ওভাররাইটিং করছি)) মানগুলি একটি বাহ্যিক ডেটা উত্স থেকে আসে (কোনও টেবিলে ডিবিতে ইতিমধ্যে নেই)।

সারণীগুলিতে প্রতিটি মুঠোয় সূচক রয়েছে এবং বিদেশী কী বাধা নেই। শেষ পর্যন্ত কোনও কমিট তৈরি করা হয় না।

pg_dumpপুরো ডিবি এর একটি আমদানি করতে 2 ঘন্টা লাগে । এটি একটি বেসলাইনের মতো মনে হচ্ছে আমাদের যুক্তিসঙ্গতভাবে লক্ষ্য করা উচিত।

পুনরায় আমদানির জন্য পোস্টগ্র্রেএসকিউএল-এর জন্য কোনও ডেটা সেট পুনর্গঠন করে এমন একটি কাস্টম প্রোগ্রাম তৈরির সংক্ষিপ্ততা, আমদানির তুলনায় বাল্ক আপডেটের পারফরম্যান্স আনতে আমরা কি কিছু করতে পারি? (এটি এমন একটি অঞ্চল যা আমরা বিশ্বাস করি যে লগ-কাঠামোগত মার্জ গাছগুলি ভালভাবে পরিচালনা করে তবে আমরা পোস্টগ্র্রেএসকিউএল-তে কিছু করতে পারি কিনা তা ভাবছি))

কিছু ধারণা:

  • সমস্ত নন-আইডি সূচকগুলি বাদ দেওয়া এবং তারপরে পুনর্নির্মাণ?
  • চেকপয়েন্ট_সেজমেন্টগুলি বাড়ছে, তবে এটি কি দীর্ঘমেয়াদী দীর্ঘমেয়াদী থ্রুপুটটিকে সহায়তা করে?
  • এখানে উল্লিখিত কৌশলগুলি ব্যবহার করছেন ? (টেবিল হিসাবে নতুন ডেটা লোড করুন, তারপরে পুরানো ডেটা যেখানে "মার্জ করুন" যেখানে নতুন ডেটাতে আইডি পাওয়া যায় না)

মূলত চেষ্টা করার মতো অনেকগুলি জিনিস রয়েছে এবং আমরা নিশ্চিত না যে সর্বাধিক কার্যকর কোনটি বা আমরা যদি অন্য বিষয়গুলি অবহেলা করি। আমরা পরের কয়েক দিন পরীক্ষায় ব্যয় করব, তবে আমরা ভেবেছিলাম আমরা এখানেও জিজ্ঞাসা করব।

আমার টেবিলে একযোগে বোঝা রয়েছে তবে এটি কেবল পঠনযোগ্য।


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

@ এরউইন ব্র্যান্ডসটেটার ধন্যবাদ, আমার প্রশ্ন আপডেট করেছে।
ইয়াং

আমি ধরে নিলাম আপনি explain analyzeএটির মাধ্যমে পরীক্ষা করেছেন যে এটি অনুসন্ধানের জন্য কোনও সূচক ব্যবহার করছে?
রজারডপ্যাক

উত্তর:


45

অনুমিতি

যেহেতু প্রশ্নটিতে তথ্য অনুপস্থিত, আমি ধরে নিব:

  • আপনার ডেটাবেস ডাটাবেস সার্ভারের একটি ফাইল থেকে আসে।
  • লক্ষ্য সারণির সাথে মেলে প্রতি সারি অনন্যCOPY এক সাথে আউটপুটের মতোই ডেটা ফর্ম্যাট করা হয় । যদি তা না হয় তবে প্রথমে এটি সঠিকভাবে ফর্ম্যাট করুন বা বিন্যাসটি মোকাবেলার জন্য বিকল্পগুলি ব্যবহার করুন। id
    COPY
  • আপনি লক্ষ্য সারণীতে বা তাদের বেশিরভাগের প্রতিটি একক সারি আপডেট করছেন।
  • আপনি লক্ষ্য সারণীটি ড্রপ এবং পুনরায় তৈরি করতে পারবেন।
    এর অর্থ কোনও একযোগে অ্যাক্সেস নেই। অন্য এই সম্পর্কিত উত্তর বিবেচনা করুন:
  • সূচক বাদে কোনও নির্ভরযোগ্য অবজেক্ট নেই are

সমাধান

আমি আপনাকে আপনার তৃতীয় বুলেট থেকে লিঙ্কে বর্ণিত অনুরূপ পদ্ধতির সাথে যেতে পরামর্শ দিই । বড় অপটিমাইজেশন সহ।

অস্থায়ী সারণী তৈরি করতে, একটি সহজ এবং দ্রুততর উপায় রয়েছে:

CREATE TEMP TABLE tmp_tbl AS SELECT * FROM tbl LIMIT 0;

ডাটাবেসের অভ্যন্তরেUPDATE একটি অস্থায়ী টেবিল থেকে একক বৃহত্তর বেশ কয়েকটি আদেশের দ্বারা ডাটাবেসের বাইরে থেকে পৃথক আপডেটগুলির চেয়ে দ্রুত হবে।

ইন পোস্টগ্রি এর MVCC মডেল , একটি UPDATEউপায়ে একটি নতুন সারি সংস্করণ তৈরি এবং মোছা পুরানো এক চিহ্নিত করতে। এটি প্রায় INSERTএবং DELETEএকত্রিত হিসাবে ব্যয়বহুল । এছাড়াও, এটি আপনাকে প্রচুর মরা টিপলস দেয়। যেহেতু আপনি পুরো টেবিলটিকে যাইহোক আপডেট করছেন, তাই কেবলমাত্র একটি নতুন টেবিল তৈরি করতে এবং পুরানোটি ফেলে দেওয়ার পক্ষে এটি সামগ্রিকভাবে দ্রুত হবে।

আপনার যদি পর্যাপ্ত পরিমাণে র্যাম উপলব্ধ থাকে তবে আপনি temp_buffersকেবল কিছু করার আগে (কেবলমাত্র এই অধিবেশনটির জন্য!) টেম্প টেম্পলটি র‍্যামে ধারণ করার জন্য যথেষ্ট উচ্চ সেট করুন ।

কতটা র‌্যামের প্রয়োজন তা অনুমান করতে, একটি ছোট নমুনা দিয়ে একটি পরীক্ষা চালান এবং ডিবি অবজেক্ট সাইজের ফাংশন ব্যবহার করুন :

SELECT pg_size_pretty(pg_relation_size('tmp_tbl'));  -- complete size of table
SELECT pg_column_size(t) FROM tmp_tbl t LIMIT 10;  -- size of sample rows

সম্পূর্ণ স্ক্রিপ্ট

SET temp_buffers = '1GB';        -- example value

CREATE TEMP TABLE tmp_tbl AS SELECT * FROM tbl LIMIT 0;

COPY tmp_tbl FROM '/absolute/path/to/file';

CREATE TABLE tbl_new AS
SELECT t.col1, t.col2, u.field1, u.field2
FROM   tbl     t
JOIN   tmp_tbl u USING (id);

-- Create indexes like in original table
ALTER TABLE tbl_new ADD PRIMARY KEY ...;
CREATE INDEX ... ON tbl_new (...);
CREATE INDEX ... ON tbl_new (...);

-- exclusive lock on tbl for a very brief time window!
DROP TABLE tbl;
ALTER TABLE tbl_new RENAME TO tbl;

DROP TABLE tmp_tbl; -- will also be dropped at end of session automatically

একযোগে বোঝা

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

আপডেট রুট

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

আমি ব্যবহার একটি অনুরূপ পদ্ধতি রূপরেখা UPDATEমধ্যে তাই এই ঘনিষ্ঠভাবে সম্পর্কিত উত্তর

 


1
আমি আসলে লক্ষ্য সারণীতে সারিগুলির 20% আপডেট করছি - সবকটিই নয়, তবে একটি বড় পরিমাণে অংশ যে একীভূত হওয়া সম্ভবত এলোমেলো আপডেটের চেয়ে ভাল।
ইয়াং

1
@AryehLeibTaurog: যে যেহেতু ঘটছে করা উচিত নয় DROP TABLEএকটি লাগে Access Exclusive Lock। যে কোনও উপায়ে, আমি ইতিমধ্যে আমার উত্তরের পূর্ব শর্তটিকে তালিকাভুক্ত করেছি: You can afford to drop and recreate the target table.লেনদেনের শুরুতে এটি টেবিলটি লক করতে সহায়তা করতে পারে। আমি আপনাকে আপনার পরিস্থিতির সমস্ত প্রাসঙ্গিক বিবরণ দিয়ে একটি নতুন প্রশ্ন শুরু করার পরামর্শ দিচ্ছি যাতে আমরা এর নীচে পৌঁছে যেতে পারি।
এরউইন ব্র্যান্ডসটেটার

1
টুইটারে এটি সার্ভার সংস্করণের উপর নির্ভর করে বলে মনে হচ্ছে। আমি 8.4 এবং 9.1 তে থাকা ত্রুটির পুনরুত্পাদন আছে psycopg2 অ্যাডাপ্টারের ব্যবহার এবং psql ক্লায়েন্ট ব্যবহার । 9.3 এ কোনও ত্রুটি নেই। প্রথম স্ক্রিপ্টে আমার মন্তব্য দেখুন। আমি এখানে পোস্ট করার জন্য কোনও প্রশ্ন আছে কিনা তা নিশ্চিত নই, তবে পোস্টগ্র্যাসিকাল তালিকার একটিতে কিছু তথ্য চাওয়ার পক্ষে মূল্য হতে পারে।
আরেহ লাইব বৃষ

1
প্রক্রিয়াটি স্বয়ংক্রিয় করার জন্য অজগরটিতে আমি একটি সাধারণ সহায়ক শ্রেণি লিখেছি ।
আরেহ লাইব বৃষ

3
খুব দরকারী উত্তর। কিছুটা ভিন্নতা হিসাবে, কেউ কেবলমাত্র কলামগুলি আপডেট করার জন্য এবং রেফারেন্সের কলামগুলি সহ অস্থায়ী টেবিল তৈরি করতে পারে, মূল টেবিল থেকে আপডেট হওয়া কলামগুলি মুছতে পারে, তারপরে সারণীগুলি মার্জ করে CREATE TABLE tbl_new AS SELECT t.*, u.field1, u.field2 from tbl t NATURAL LEFT JOIN tmp_tbl u;, LEFT JOINযার জন্য কোনও আপডেট নেই। অবশ্যই যে NATURALকোনও বৈধ USING()বা ON
স্কিপি লে গ্র্যান্ড গৌরু

2

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


3
"টার্গেট টেবিলের সাথে একত্রীকরণ" বলতে বিশেষত আপনার অর্থ কী? কেন একটি টেম্প টেবিলের সিপাইয়ের চেয়ে এফডিডাব্লু ব্যবহার করা ভাল (মূল প্রশ্নের তৃতীয় বুলেটটিতে পরামর্শ দেওয়া হয়েছে)?
ইয়াং

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

1
@ ডেভিডএলড্রিজ: এসকিউএল: 2003 স্ট্যান্ডার্ডে সংজ্ঞায়িত করা হলেও MERGEপোস্টগ্র্রেএসকিউএল (এখনও) প্রয়োগ করা হয়নি। অন্যান্য আরডিবিএমএসের প্রয়োগগুলি কিছুটা আলাদা হয়। MERGEএবং এর জন্য ট্যাগ তথ্য বিবেচনা করুন UPSERT
এরউইন ব্র্যান্ডস্টেটর

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