সমস্যাটি
আমাদের মত একটি প্রশ্ন আছে
SELECT COUNT(1)
FROM article
JOIN reservation ON a_id = r_article_id
WHERE r_last_modified < now() - '8 weeks'::interval
AND r_group_id = 1
AND r_status = 'OPEN';
যেহেতু এটি প্রায়শই বেশি সময়সীমা (10 মিনিটের পরে) চলে যায়, তাই আমি বিষয়টি তদন্তের সিদ্ধান্ত নিয়েছি।
EXPLAIN (ANALYZE, BUFFERS)
আউটপুট ভালো দেখায়:
Aggregate (cost=264775.48..264775.49 rows=1 width=0) (actual time=238960.290..238960.291 rows=1 loops=1)
Buffers: shared hit=200483 read=64361 dirtied=666 written=8, temp read=3631 written=3617
I/O Timings: read=169806.955 write=0.154
-> Hash Join (cost=52413.67..264647.65 rows=51130 width=0) (actual time=1845.483..238957.588 rows=21644 loops=1)
Hash Cond: (reservation.r_article_id = article.a_id)
Buffers: shared hit=200483 read=64361 dirtied=666 written=8, temp read=3631 written=3617
I/O Timings: read=169806.955 write=0.154
-> Index Scan using reservation_r_article_id_idx1 on reservation (cost=0.42..205458.72 rows=51130 width=4) (actual time=34.035..237000.197 rows=21644 loops=1)
Filter: ((r_group_id = 1) AND (r_status = 'OPEN') AND (r_last_modified < (now() - '56 days'::interval)))
Rows Removed by Filter: 151549
Buffers: shared hit=200193 read=48853 dirtied=450 written=8
I/O Timings: read=168614.105 write=0.154
-> Hash (cost=29662.22..29662.22 rows=1386722 width=4) (actual time=1749.392..1749.392 rows=1386814 loops=1)
Buckets: 32768 Batches: 8 Memory Usage: 6109kB
Buffers: shared hit=287 read=15508 dirtied=216, temp written=3551
I/O Timings: read=1192.850
-> Seq Scan on article (cost=0.00..29662.22 rows=1386722 width=4) (actual time=23.822..1439.310 rows=1386814 loops=1)
Buffers: shared hit=287 read=15508 dirtied=216
I/O Timings: read=1192.850
Total runtime: 238961.812 ms
বাধা নোড স্পষ্টতই সূচক স্ক্যান। সুতরাং আসুন সূচী সংজ্ঞাটি দেখুন:
CREATE INDEX reservation_r_article_id_idx1
ON reservation USING btree (r_article_id)
WHERE (r_status <> ALL (ARRAY['FULFILLED', 'CLOSED', 'CANCELED']));
আকার এবং সারি সংখ্যা
এটির আকার ( \di+
শারীরিক ফাইল দ্বারা বা পরিদর্শন করে রিপোর্ট করা হয়েছে ) এটি 36 এমবি। যেহেতু সংরক্ষণগুলি উপরে বর্ণিত সমস্ত স্ট্যাটাসে কেবলমাত্র তুলনামূলকভাবে স্বল্প সময় ব্যয় করে, অনেকগুলি আপডেট হচ্ছে happening তাই সূচকটি বেশ ফেটে গেছে (প্রায় 24 এমবি এখানে নষ্ট হয়) - তবুও আকারটি তুলনামূলকভাবে কম।
reservation
টেবিল আকারে 3.8 গিগাবাইট সম্পর্কে প্রায় 40 মিলিয়ন সারি রয়েছে। যে রিজার্ভেশনগুলি এখনও বন্ধ হয়নি তা প্রায় 170,000 (সঠিক নম্বরটি উপরে সূচক স্ক্যান নোডে রিপোর্ট করা হয়েছে) reported
এখন আশ্চর্য: সূচক স্ক্যানটি বিপুল পরিমাণে বাফার (অর্থাৎ 8 কেবি পৃষ্ঠা) আনার প্রতিবেদন করেছে:
Buffers: shared hit=200193 read=48853 dirtied=450 written=8
ক্যাশে এবং ডিস্ক (বা ওএস ক্যাশে) থেকে পড়া সংখ্যাগুলি 1.9 গিগাবাইট পর্যন্ত যোগ করে!
সবচেয়ে খারাপ পরিস্থিতি
অন্যদিকে, সবচেয়ে খারাপ পরিস্থিতি, যখন প্রতিটি টুপল টেবিলের ভিন্ন পৃষ্ঠায় বসে, 2184 + 151549 + 4608 পৃষ্ঠাগুলিতে পরিদর্শন করে (মোট সারি টেবিল থেকে আনতে পারে এবং শারীরিক থেকে সূচী পৃষ্ঠা নম্বরটি) সাইজ)। এটি এখনও কেবল 180,000 এর নিচে রয়েছে - পর্যবেক্ষণ করা প্রায় 250,000 এর নিচে।
আকর্ষণীয় (এবং সম্ভবত গুরুত্বপূর্ণ) হ'ল ডিস্ক পড়ার গতি প্রায় ২.২ এমবি / সেকেন্ডের মতো, যা বেশ স্বাভাবিক, আমার ধারণা।
তাতে কি?
এই তাত্পর্যটি কোথা থেকে আসতে পারে সে সম্পর্কে কারও কি ধারণা আছে?
দ্রষ্টব্য: পরিষ্কার করার জন্য, আমাদের এখানে কী কী উন্নতি / পরিবর্তন করতে হবে সে সম্পর্কে আমাদের ধারণা রয়েছে তবে আমি যে নম্বর পেয়েছি তা বুঝতে চাই - এই প্রশ্নটিই এটি।
আপডেট: ক্যাচিং বা মাইক্রোভ্যাকুমিংয়ের প্রভাব পরীক্ষা করা
জাজানসের উত্তরের ভিত্তিতে , আমি ঠিক একই ক্যোয়ারীটি সরাসরি সরাসরি চালানোর পরে কী হবে তা আমি পরীক্ষা করেছি। ক্ষতিগ্রস্থ বাফারদের সংখ্যা আসলেই পরিবর্তিত হয় না। (এটি করার জন্য, আমি ক্যোয়ারীটিকে তার ন্যূনতম থেকে সরল করেছিলাম যা এখনও সমস্যাটি দেখায়)) প্রথম রান থেকে এটিই আমি দেখছি:
Aggregate (cost=240541.52..240541.53 rows=1 width=0) (actual time=97703.589..97703.590 rows=1 loops=1)
Buffers: shared hit=413981 read=46977 dirtied=56
I/O Timings: read=96807.444
-> Index Scan using reservation_r_article_id_idx1 on reservation (cost=0.42..240380.54 rows=64392 width=0) (actual time=13.757..97698.461 rows=19236 loops=1)
Filter: ((r_group_id = 1) AND (r_status = 'OPEN') AND (r_last_modified < (now() - '56 days'::interval)))
Rows Removed by Filter: 232481
Buffers: shared hit=413981 read=46977 dirtied=56
I/O Timings: read=96807.444
Total runtime: 97703.694 ms
এবং দ্বিতীয়টির পরে:
Aggregate (cost=240543.26..240543.27 rows=1 width=0) (actual time=388.123..388.124 rows=1 loops=1)
Buffers: shared hit=460990
-> Index Scan using reservation_r_article_id_idx1 on reservation (cost=0.42..240382.28 rows=64392 width=0) (actual time=0.032..385.900 rows=19236 loops=1)
Filter: ((r_group_id = 1) AND (r_status = 'OPEN') AND (r_last_modified < (now() - '56 days'::interval)))
Rows Removed by Filter: 232584
Buffers: shared hit=460990
Total runtime: 388.187 ms
pg_stat_reset()
পারেন, এবং তারপরে কোয়েরিটি চালাতে পারেন এবং তারপরে pg_statio_user_tables
এটি কোথায় ব্লকগুলিকে বৈশিষ্ট্যযুক্ত তা সন্ধান করুন।
article
? জড়িত সমস্ত কলামগুলিreservation
টেবিলের মতো মনে হচ্ছে এবং (ধরে নিচ্ছি) কোনও এফকে রয়েছে, ফলাফলটি একই হওয়া উচিত।