পোস্টগ্রিএসকিউএল, ওয়ার্কআউন্ডে খুব ধীর মোছা?


30

আমার পোস্টগ্রিজ এসকিউএল 9.2 এ একটি ডাটাবেস রয়েছে যার প্রায় 70 টি টেবিল এবং প্রতিটি 30 টি টেবিলের প্রতি ক্লায়েন্ট স্কিমার মতো স্বতন্ত্রভাবে কাঠামোগত সংখ্যার সাথে একটি মূল স্কিমা রয়েছে। ক্লায়েন্ট স্কিমে বিদেশী কীগুলি মূল স্কিমা উল্লেখ করে অন্য উপায়ে নয়।

আমি সবেমাত্র পূর্ববর্তী সংস্করণ থেকে নেওয়া কিছু বাস্তব তথ্য দিয়ে ডাটাবেস পূরণ শুরু করেছি filling মূল স্কিমাতে খুব কেন্দ্রীয় টেবিলে আমাকে বাল্ক মুছতে হবে যখন ডিবি প্রায় 1.5 গিগাবাইটে পৌঁছেছিল (এটি কয়েক সপ্তাহের মধ্যে বেশ কয়েকটি 10 ​​জিবিতে বাড়বে বলে আশা করা হচ্ছে)। সমস্ত সম্পর্কিত বিদেশী কীগুলি মুছে ফেলা নগদভাবে চিহ্নিত করা হয়েছে।

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

এটি কি আরও দ্রুত হতে পারে যদি আমি কোনও স্ক্রিপ্ট লিখে থাকি যা নির্ভর করে টেবিলগুলি কেন্দ্রীয় টেবিলের সারণি থেকে শুরু করে টেবিলের মাধ্যমে নির্ভরশীল সারি টেবিলটি মুছে ফেলা যায়?

একটি গুরুত্বপূর্ণ বিশদটি হ'ল কয়েকটি টেবিলে ট্রিগার রয়েছে।


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

উত্তর:


30

আমারও একই সমস্যা ছিল। দেখা যাচ্ছে যে এই ON DELETE CASCADEট্রিগারগুলি কিছুটা ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ছিল because

আমি রেফারেন্সিং টেবিলগুলিতে বিদেশী কী ক্ষেত্রগুলিতে সূচী তৈরি করে সমস্যার সমাধান করেছি এবং মুছে ফেলার জন্য কয়েক ঘন্টা সময় নিলাম এবং কয়েক সেকেন্ডে চলে গেলাম।


বাহ, এটি আমাকে কয়েক মিনিটের মধ্যে 8 এম রেকর্ড মুছতে সহায়তা করেছে। তবে আমি যা বুঝতে পারি না তা হ'ল আমার টেবিলটি কেবলমাত্র অন্য টেবিলগুলিতে রেফারেন্স রাখে, অন্য কোনও টেবিলগুলি আমার টেবিলে রেফারেন্স রাখে না। সুতরাং ঠিক এখানে প্রভাব কি? (আমি ব্যবহার করছি না ON DELETE CASCADE)
msrd0

2
এটি আমার জন্য এটিও সমাধান করেছে। যে কেউ এই চেষ্টা করছেন, আপনি EXPLAIN (ANALYZE, BUFFERS)একটি একক সারি মুছে ফেলার বিষয়ে একটি জিজ্ঞাসা করতে পারেন এবং এটি আপনাকে দেখাতে পারে যে কোন বিদেশী কী সীমাবদ্ধতা সবচেয়ে দীর্ঘ সময় নিয়েছে (কমপক্ষে এটি আমার পক্ষে হয়েছিল)।
জাস্টিন কর্মী 4'18

একই, ক্যাসকেড 600k সারিগুলিতে মুছতে হয়েছিল এবং শুরুতে এটি 100% সিপিইউ ব্যবহারের সাথে অপারেশন প্রতি 2-10 এর মধ্যে নিয়েছিল। 80% সিপিইউ ব্যবহারের সাথে সেগুলি মুছতে এখন কয়েক মিনিট সময় লেগেছে।
ফিলোবোটো

এটি লক্ষ করা গুরুত্বপূর্ণ যে আপনার যদি কোথাও কোনও বিদেশী রেফারেন্স থাকে তবে উত্স কলামে আসল সূচক থাকতে হবে বা সম্পাদনা ক্ষতিগ্রস্থ হবে। আমি নিশ্চিত নই যে PRIMARYসূচি যথেষ্ট কিনা তবে সূচক UNIQUEঅবশ্যই এই উদ্দেশ্যে যথেষ্ট ভাল নয়।
মিক্কো রেন্টালাইনেন

26

আপনার স্বল্প কিছু সু্যোগ আছে। সেরা ব্যাচটি হ'ল ব্যাচটি মুছুন যাতে ট্রিগারগুলি হিট না হয়। মোছার আগে ট্রিগারগুলি অক্ষম করুন, তারপরে তাদের পুনরায় সক্ষম করুন। এটি আপনাকে খুব বড় পরিমাণে সময় সাশ্রয় করে। উদাহরণ স্বরূপ:

ALTER TABLE tablename DISABLE TRIGGER ALL; 
DELETE ...; 
ALTER TABLE tablename ENABLE TRIGGER ALL;

এখানে একটি প্রধান কী হ'ল আপনি সাবকিউয়ের গভীরতা হ্রাস করতে চান। এই ক্ষেত্রে আপনি প্রাসঙ্গিক তথ্য সংরক্ষণের জন্য টেম্প টেবিলগুলি সেট আপ করতে চাইতে পারেন যাতে আপনি আপনার মোছার উপর গভীর সাবকিউরিগুলি এড়াতে পারেন।


আমার ক্ষেত্রে, আমি বিছানায় যাওয়ার আগে ডিলিট FROM কমান্ডটি শুরু করেছিলাম এবং পরের দিন আমার কম্পিউটারে ফিরে আসার পরে এটি করা হয়নি। পুরো সময়টিতে একটি কোরতে 100% সিপিইউ ব্যবহার। ট্রিগারগুলি অক্ষম করার পরে এবং আবার চেষ্টা করার পরে 200 কে রেকর্ড মুছতে 3 সেকেন্ড সময় লেগেছে। ধন্যবাদ!
নিক উডহামস

13

সমস্যা সমাধানের জন্য সবচেয়ে সহজ পদ্ধতিতে পোস্টগ্রি থেকে বিস্তারিত সময়ের অনুসন্ধান করা: EXPLAIN। এর জন্য আপনাকে সর্বনিম্ন একক ক্যোয়ারী সন্ধান করতে হবে যা সম্পূর্ণ হয় তবে প্রত্যাশার চেয়ে বেশি সময় নেয়। এই লাইনটি দেখতে দেখতে বলে দিন

delete from mydata where id='897b4dde-6a0d-4159-91e6-88e84519e6b6';

পরিবর্তে সত্যিই যে কমান্ড চালানো আপনি করতে পারেন

begin;
explain (analyze,buffers,timing) delete from mydata where id='897b4dde-6a0d-4159-91e6-88e84519e6b6';
rollback;

শেষের দিকে রোলব্যাকটি ডাটাবেসটিতে কোনও পরিবর্তন না করেই এটি চালানোর অনুমতি দেয় তবে আপনি এখনও কতটা নিয়েছিলেন তার বিশদ সময় পাবেন। এটি চালানোর পরে, আপনি আউটপুটটিতে দেখতে পাবেন যে কিছু ট্রিগার বিপুল বিলম্বের কারণ:

...
Trigger for constraint XYZ123: time=12311.292 calls=1
...

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

একবার আপনি এই সীমাবদ্ধতার (বা অন্য কোনও জিনিস যা অতিরিক্ত দীর্ঘ সময় নিয়েছিল) স্থির করে ফেলেছেন begin/ / rollbackব্লকের কমান্ডটি পুনরাবৃত্তি করুন যাতে আপনি নতুন এক্সিকিউশন সময়টিকে পূর্বের সাথে তুলনা করতে পারেন। একক লাইন প্রতিক্রিয়া সময় মোছার সাথে আপনি খুশি না হওয়া অবিরত অবিরত করুন (কেবল আলাদা সূচকগুলি যোগ করে 25.6 সেকেন্ড থেকে 15 এমএসে যেতে আমার একটি ক্যোয়ারী পেয়েছে)। তারপরে আপনি কোনও হ্যাক ছাড়াই আপনার সম্পূর্ণ মোছার কাজটি এগিয়ে নিয়ে যেতে পারেন।

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


8

ট্রিগার অক্ষম করা ডিবি অখণ্ডতার জন্য হুমকি হতে পারে এবং এটি সুপারিশ করা যায় না; তবে আপনি যদি নিশ্চিত হন যে আপনার অপারেশন সীমাবদ্ধতা-ব্যর্থতা-প্রমাণ, আপনি নিম্নলিখিতগুলি সহ ট্রিগারগুলি অক্ষম করতে পারেন:SET session_replication_role = replica;

DELETEএখানে চালান ।

ট্রিগারগুলি পুনরুদ্ধার করতে, চালান: SET session_replication_role = DEFAULT;

উত্স এখানে।


0

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

CREATE TABLE tablea (
    tablea_uid integer
);

CREATE TABLE tableb (
    tableb_uid integer,
    tablea_rid integer REFERENCES tablea(tablea_uid)
);

CREATE TABLE tablec (
    tablec_uid integer,
    tableb_rid integer REFERENCES tableb(tableb_uid)
);

সেক্ষেত্রে টেবিলের পরে টেবিলের পরে টেবিলের ডেটা মুছুন

CREATE OR REPLACE FUNCTION delete_in_order()
 RETURNS void AS $$

    DELETE FROM tablec;
    DELETE FROM tableb;
    DELETE FROM tablea;

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