পোস্টগ্রিসের আপডেটটি কেন 39 ঘন্টা সময় নিয়েছে?


17

আমার কাছে g 2.1 মিলিয়ন সারি সহ একটি পোস্টগ্রিস টেবিল রয়েছে। আমি এটিতে নীচের আপডেটটি চালিয়েছি:

WITH stops AS (
    SELECT id,
           rank() OVER (ORDER BY offense_timestamp,
                     defendant_dl,
                     offense_street_number,
                     offense_street_name) AS stop
    FROM   consistent.master
    WHERE  citing_jurisdiction=1
)

UPDATE consistent.master
SET arrest_id=stops.stop
FROM stops
WHERE master.id = stops.id;

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

কোয়েরিটি চলমান পুরো সময়টি, কমপক্ষে প্রাথমিক WITHসম্পন্ন হওয়ার পরে , সিপিইউ ব্যবহার সাধারণত কম ছিল, এবং এইচডিডি ব্যবহার করা হয়েছিল 100%। এইচডিডি এত কঠোরভাবে ব্যবহৃত হচ্ছে যে অন্য কোনও অ্যাপ্লিকেশন স্বাভাবিকের চেয়ে বেশ ধীরে ধীরে চলছিল।

ল্যাপটপের পাওয়ার সেটিং উচ্চ কার্যকারিতা (উইন্ডোজ 7 এক্স 64) এ ছিল।

এখানে ব্যাখ্যা দিন:

Update on master  (cost=822243.22..1021456.89 rows=2060910 width=312)
  CTE stops
    ->  WindowAgg  (cost=529826.95..581349.70 rows=2060910 width=33)
          ->  Sort  (cost=529826.95..534979.23 rows=2060910 width=33)
                Sort Key: consistent.master.offense_timestamp, consistent.master.defendant_dl, consistent.master.offense_street_number, consistent.master.offense_street_name
                ->  Seq Scan on master  (cost=0.00..144630.06 rows=2060910 width=33)
                      Filter: (citing_jurisdiction = 1)
  ->  Hash Join  (cost=240893.51..440107.19 rows=2060910 width=312)
        Hash Cond: (stops.id = consistent.master.id)
        ->  CTE Scan on stops  (cost=0.00..41218.20 rows=2060910 width=48)
        ->  Hash  (cost=139413.45..139413.45 rows=2086645 width=268)
              ->  Seq Scan on master  (cost=0.00..139413.45 rows=2086645 width=268)

citing_jurisdiction=1কয়েক হাজার কয়েক সারি বাদ দেয়। এমনকি এই WHEREধারাটি সহ, আমি এখনও 2 মিলিয়ন সারিতে অপারেটিং করছি operating

হার্ড ড্রাইভটি ট্রুক্রিপ্ট 7.1a এর সাথে পুরো ড্রাইভ-এনক্রিপ্টড। একটু নিচে যে গতি জিনিষ, কিন্তু না যথেষ্ট একটি ক্যোয়ারী নিতে কারণ যে অনেক ঘন্টা।

WITHঅংশ মাত্র 3 মিনিট চালানোর সময় লাগে।

arrest_idক্ষেত্র বিদেশী কী-এর জন্য কোন সূচক ছিল। এই টেবিলটিতে 8 টি সূচক এবং 2 বিদেশী কী রয়েছে। ক্যোয়ারির অন্যান্য ক্ষেত্রগুলি সূচীভূত।

arrest_idক্ষেত্র ছাড়া সীমাবদ্ধতা ছিল NOT NULL

সারণীতে মোট 32 টি কলাম রয়েছে।

arrest_idবিভিন্ন ধরণের চরিত্রের (20) হয় । আমি বুঝতে পারি যে rank()একটি সংখ্যাসূচক মান উত্পন্ন হয়, তবে আমাকে পৃথকীকরণের অক্ষর ব্যবহার করতে হবে (20) কারণ আমার অন্যান্য সারি রয়েছে যেখানে citing_jurisdiction<>1এই ক্ষেত্রটির জন্য অ-সংখ্যাসূচক ডেটা ব্যবহার করা হয়।

arrest_idক্ষেত্র সহ সব সারি জন্য ফাঁকা ছিল citing_jurisdiction=1

এটি একটি ব্যক্তিগত, উচ্চ প্রান্ত (1 বছর আগের হিসাবে) ল্যাপটপ। আমি একমাত্র ব্যবহারকারী অন্য কোনও অনুসন্ধান বা ক্রিয়াকলাপ চলছে না। লক করা অসম্ভব বলে মনে হচ্ছে।

এই টেবিলের কোথাও বা ডাটাবেসে অন্য কোথাও কোনও ট্রিগার নেই।

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


এগুলি Seq Scanকিছুটা ভীতিজনক ...
রজারডপ্যাক

উত্তর:


18

আমি 3.5 মিলিয়ন সারিগুলির একটি টেবিলের সাথে সম্প্রতি এমন কিছু ঘটেছিলাম। আমার আপডেট কখনও শেষ হবে না। অনেক পরীক্ষা-নিরীক্ষা ও হতাশার পরে অবশেষে আমি অপরাধীকে খুঁজে পেলাম। এটি আপডেট হওয়া টেবিলের সূচকগুলিতে পরিণত হয়েছিল।

সমাধানটি হ'ল আপডেট বিবৃতি চালানোর আগে আপডেট হওয়া টেবিলের সমস্ত সূচিপত্র বাদ দেওয়া। একবার আমি এটি করেছিলাম, আপডেটটি কয়েক মিনিটের মধ্যে শেষ হয়েছিল। আপডেটটি শেষ হয়ে গেলে আমি আবার সূচিগুলি তৈরি করে আবার ব্যবসায়ে ফিরে আসি। এটি সম্ভবত আপনাকে এই মুহুর্তে সহায়তা করবে না তবে এটির উত্তর খুঁজছেন অন্য কেউ হতে পারে।

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


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

1
ধন্যবাদ! আশা করি এটি অন্যকে সহায়তা করবে। আপাতদৃষ্টিতে খুব সাধারণ কিছু বলে এটি আমার কয়েক ঘন্টা মাথা ব্যাথা বাঁচিয়ে দিত।
জেসি আভেনা

5
@ আরেনকাম্ব্রে - এর একটি কারণ রয়েছে: পোস্টগ্র্যাস এসকিউএল সম্পূর্ণ সারিটি অন্য কোনও স্থানে অনুলিপি করে এবং পুরানো সংস্করণটিকে মুছে ফেলা হিসাবে চিহ্নিত করে। পোস্টগ্র্রেএসকিউএল এইভাবে মাল্টি-ভার্সন কনকুরન્સી নিয়ন্ত্রণ (এমভিসিসি) প্রয়োগ করে।
পাইওটার ফাইন্ডেইন

আমার প্রশ্ন ... এটা অপরাধী কেন? আরও দেখুন stackoverflow.com/a/35660593/32453
rogerdpack

15

আপনার বৃহত্তম সমস্যাটি ল্যাপটপের হার্ড ড্রাইভে প্রচুর পরিমাণে লিখন-ভারী, সন্ধানী-ভারী কাজ করছে। আপনি যা-ই করুন না কেন এটি কখনই দ্রুত হতে পারে না, বিশেষত যদি ধীরে ধীরে ধীরে ধীরে 5400 আরপিএম ড্রাইভ প্রচুর ল্যাপটপে চালিত হয় in

ট্রুক্রিপ্ট লেখাগুলির জন্য "কিছুটা" বেশি কিছু কমিয়ে দেয়। পঠনগুলি যুক্তিসঙ্গতভাবে দ্রুত হবে তবে লেখাগুলি RAID 5 কে দ্রুত দেখায়। ট্রুক্রিপট ভলিউমে একটি ডিবি চালানো লেখকদের জন্য নির্যাতনযোগ্য হবে, বিশেষত এলোমেলো লেখার জন্য।

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

BEGIN;
SELECT ... INTO TEMPORARY TABLE master_tmp ;
TRUNCATE TABLE consistent.master;
-- Now DROP all constraints on consistent.master, then:
INSERT INTO consistent.master SELECT * FROM master_tmp;
-- ... and re-create any constraints.

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

আপনি একেবারে আপ-টু-ডেট ব্যাকআপ আছে এবং ব্যাকআপ থেকে আপনার ডাটাবেস পূর্বাবস্থায় ফিরিয়ে আনুন থাকার কিছু মনে না করেন আপনার কাছে পোস্টগ্রি পুনরায় শুরু করতে পারেন fsync=offপরামিতি এবং full_page_writes=off সাময়িকভাবে এই বাল্ক অপারেশন জন্য। বিদ্যুৎ হ্রাস বা কোনও ওএস ক্র্যাশের মতো কোনও অপ্রত্যাশিত সমস্যা আপনার ডাটাবেসটিকে অপরিবর্তনীয় রাখবে fsync=off

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

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


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

1
ফিলফ্যাক্টরের সাহায্যে HOTs সম্ভাবনা বাড়িয়ে তোলার পক্ষে ভাল কল - যদিও ট্রুক্রিপ্ট বিশাল ব্লকে ব্লক রিড-রাইটারিট চক্রকে বাধ্য করছে আমি নিশ্চিত নই যে এটি বেশি সাহায্য করবে; সারি মাইগ্রেশন এমনকি দ্রুত হতে পারে কারণ টেবিলের বর্ধন করা কমপক্ষে রৈখিক-ইশ ব্লকের লেখার কাজ করে।
ক্রেগ রিঞ্জার

2.5 বছর পরে আমি অনুরূপ কিছু করছি তবে বড় টেবিলে on কেবলমাত্র নিশ্চিত করার জন্য, আমি যে একক কলামটি আপডেট করছি তা যদি সূচিকৃত না হয়, তবে কী সমস্ত সূচকে বাদ দেওয়া ভাল ধারণা?
অ্যারেন কাম্ব্রে

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

ধন্যবাদ। এই ক্ষেত্রে এটি একটি বুলিয়ান কলাম যা ইতিমধ্যে প্রতিটি সারিতে প্রবেশ করেছে। আমি কিছু সারি এন্ট্রি পরিবর্তন ছিল। আমি কেবল নিশ্চিত করেছি: সমস্ত সূচি বাদ দেওয়ার পরে আপডেটটি মাত্র 2 ঘন্টা সময় নেয়। পূর্বে, আমাকে 18 ঘন্টা পরে আপডেটটি থামাতে হয়েছিল কারণ এটি কেবল খুব বেশি সময় নিচ্ছিল। এটি নিশ্চিত হওয়া সত্ত্বেও যে কলামটি অবশ্যই আপডেট হয়েছিল তা সূচিযুক্ত হয়নি not
আরেন কাম্ব্রে

2

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

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

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

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


পোস্টগ্রিএসকিউএল একটি দীর্ঘ রোলব্যাক নিয়ে সমস্যা নেই, বিদ্যমান নেই। রোলব্যাক পোস্টগ্রিএসকিউএলএ খুব দ্রুত, আপনার লেনদেন যত বড় হোক না কেন। ওরাকল! = পোস্টগ্রিসএসকিউএল
ফ্র্যাঙ্ক হিকেন্স

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

2
@ গ্লেন পোস্টগ্রিস টেবিলের মধ্যে একটি সারির সংস্করণ রাখে - ব্যাখ্যাটির জন্য এখানে দেখুন । আপসটি হ'ল আপনি 'মৃত' টিউপসগুলি চারদিকে ঝুলন্ত অবস্থায় পেয়েছেন, যা পোস্টগ্রিসে 'ভ্যাকুয়াম' বলে অবিচ্ছিন্নভাবে পরিষ্কার করা হয় (ওরাকলকে শূন্যতার দরকার নেই কারণ এটি টেবিলে নিজেই কখনও 'মৃত' সারি নেই)
জ্যাক বলেছেন topanswers.xyz

আপনাকে স্বাগত জানানো হয়েছে, বরং বিরক্তিকরভাবে: সাইটে স্বাগতম :-)
জ্যাক বলেছে টপান্সওয়ার্স.অক্সিজ

@ গ্লেন পোস্টগ্র্রেএসকিউএল এর সারি সংস্করণ সম্মতি নিয়ন্ত্রণের জন্য ক্যানোনিকাল ডকুমেন্টটি postgresql.org/docs/current/static/mvcc-intro.html এবং এটি পড়ার পক্ষে উপযুক্ত। আরও দেখুন wiki.postgresql.org/wiki/MVCC । নোট করুন যে মৃত সারি সহ এমভিসিসি এবং VACUUMউত্তরটি কেবলমাত্র অর্ধেক; পোস্টগ্রি একটি তথাকথিত "লেখ এগিয়ে লগ" (কার্যকরভাবে একটি জার্নাল) পারমাণবিক করে এবং ইত্যাদি আংশিক লিখেছেন রক্ষা দেখুন ব্যবহার করে postgresql.org/docs/current/static/wal-intro.html
ক্রেগ রিঙ্গার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.