পোস্টগ্র্যাস থেকে সারি মুছে ফেলার সর্বাধিক দক্ষ উপায়


23

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

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

  • প্রাথমিক কী (বা একটি ধারা ব্যবহারের ব্যাচগুলিতে মুছে ফেলা গোষ্ঠী ) DELETEসহ ফাইলের প্রতিটি সারিটির জন্য একটি ক্যোয়ারী চালাওWHEREnIN()
  • COPYকমান্ডটি ব্যবহার করে অস্থায়ী সারণীতে প্রাথমিক কীগুলি আমদানি করুন এবং তার পরে একটি জোড় ব্যবহার করে প্রধান টেবিল থেকে মুছুন

কোন পরামর্শ অনেক প্রশংসা করা হবে!


1
একই প্রশ্নের এখানে আরও বিশদে উত্তর দেওয়া হয়েছে: stackoverflow.com/a/8290958
সাইমন

উত্তর:


25

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

এটি করার উপায় হ'ল একটি নির্বাচন এবং আপনার মোছার জন্য একটি যোগদান ব্যবহার করা।

DELETE FROM foo WHERE id IN (select id from rows_to_delete);

কোনও পরিস্থিতিতে আপনার বৃহত্তর টেবিলের সাথে নীচে নীচে থাকা উচিত নয়:

DELETE FROM foo WHERE id NOT IN (select id from rows_to_keep);

এটি সাধারণত নেস্টেড লুপ অ্যান্টিজেইন সৃষ্টি করে যা কার্য সম্পাদনকে বরং সমস্যাযুক্ত করে তুলবে। যদি আপনাকে সেই পথে যেতে হয় তবে পরিবর্তে এটি করুন:

DELETE FROM foo 
WHERE id IN (select id from foo f 
          LEFT JOIN rows_to_keep d on f.id = d.id
              WHERE d.id IS NULL);

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

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


এটি অনেক সাহায্য করেছে, ধন্যবাদ! তবে আমি দেখতে পেয়েছি যে "বিশেষত প্রশ্নগুলির সংমিশ্রণ" ব্যবহার করা এই বিশেষ ক্ষেত্রে আরও দক্ষ। যেমন IN ( select id from foo except select id from rows_to_keep ) দেখুন postgresql.org/docs/9.4/static/queries-union.html
UFOs

1

আমি এই প্রশ্নটি পেরিয়ে এসেছি কারণ আমারও একই সমস্যা ছিল। আমি এমন একটি ডাটাবেস সাফ করছি যাতে 300M + সারি রয়েছে, চূড়ান্ত ডাটাবেসে কেবল প্রায় 30% মূল ডেটা থাকবে। আপনি যদি একইরকম দৃশ্যের মুখোমুখি হন তবে নতুন টেবিলের মধ্যে সন্নিবেশ করা মুছে ফেলার পরিবর্তে পুনরায় সূচী করা সহজ।

এরকম কিছু করুন

CREATE temp_foo as SELECT * FROM foo WHERE 1=2;
INSERT INTO temp_foo (SELECT * FROM foo where foo.id IN (SELECT bar.id FROM BAR);

Foo এবং বারে যথাযথ সূচকের সাহায্যে আপনি সেক স্ক্যানগুলি এড়াতে পারবেন।

তারপরে আপনাকে পুনরায় সূচী করে টেবিলটির নতুন নামকরণ করতে হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.