30/04/2026
তুমি query তিনবার rewrite করেছ। Index দিয়েছ। EXPLAIN ANALYZE দেখেছ। তারপরও query slow। এখন কী করবে?
বেশিরভাগ ক্ষেত্রে সমস্যাটা query-তে না — সমস্যা database-এর ভেতরের physical health-এ।
─────────────────────────
🔑 আগে key terms বুঝে নাও
─────────────────────────
▸ Dead tuple — PostgreSQL-এ কোনো row UPDATE বা DELETE হলে সেই পুরনো version সাথে সাথে মুছে যায় না। সে জায়গা নিয়ে পড়ে থাকে — এটাই dead tuple।
▸ Table bloat — অনেক dead tuple জমলে table আসলের চেয়ে অনেক বড় হয়ে যায়, কিন্তু কাজের data কম।
▸ Query planner — PostgreSQL execute করার আগে সিদ্ধান্ত নেয়: Seq Scan ভালো, নাকি Index Scan? এই সিদ্ধান্ত নেওয়ার engine হলো planner।
▸ Autovacuum — PostgreSQL নিজে থেকে background-এ VACUUM চালায়। কিন্তু heavy write workload-এ এটা পিছিয়ে পড়ে।
─────────────────────────
⚙️ কী হয় আসলে?
─────────────────────────
ধর তোমার orders table-এ প্রতিদিন ৫০,০০০ row UPDATE হয়। PostgreSQL প্রতিটা UPDATE-এ নতুন version লেখে, পুরনোটা dead হয়ে পড়ে থাকে।
এক সপ্তাহ পর:
• Live rows: ৩,০০,০০০
• Dead tuples: ২,৫০,০০০
Planner statistics এখনো পুরনো — সে ভাবছে table-এ মাত্র ৮০,০০০ row আছে।
তাই planner বলে: "এত কম row? Index scan দরকার নেই, Seq Scan-ই যথেষ্ট।"
কিন্তু আসলে সে ৫,৫০,০০০ row-এর bloated table scan করছে। Query slow হওয়াটা স্বাভাবিক।
─────────────────────────
🔍 Diagnose করবে কীভাবে?
─────────────────────────
এই query চালাও:
SELECT relname, n_live_tup, n_dead_tup, last_vacuum, last_analyze
FROM pg_stat_user_tables
WHERE relname = 'orders';
যদি দেখ n_dead_tup অনেক বেশি এবং last_analyze অনেক পুরনো — তাহলে সমস্যা এখানেই।
Fix:
VACUUM ANALYZE orders;
VACUUM dead tuples সরাবে, ANALYZE planner-কে নতুন statistics দেবে।
─────────────────────────
⚠️ Common mistake
─────────────────────────
অনেকে মনে করেন autovacuum থাকলে ম্যানুয়ালি কিছু করতে হবে না।
কিন্তু heavy write workload-এ autovacuum নিজেই পিছিয়ে পড়ে — dead tuples জমতে থাকে, statistics stale হতে থাকে। Production-এ batch job বা pipeline চালানোর পর manually ANALYZE করার অভ্যাস রাখো।
আর VACUUM FULL সাবধানে — এটা table-এ exclusive lock নেয়, পুরো table rewrite করে। Production চলাকালীন এটা চালালে সব read-write ব্লক হয়ে যাবে।
─────────────────────────
🧩 Mini challenge
─────────────────────────
তোমার planner estimate দেখাচ্ছে 500 rows, কিন্তু actual rows 85,000। Query তে কোনো bug নেই।
এই mismatch-এর সবচেয়ে likely কারণ কী?
(উত্তর নিচে 👇)
...
✅ উত্তর: Stale statistics। ANALYZE অনেকদিন চলেনি, তাই planner ভুল row count দিয়ে ex*****on plan বানিয়েছে। ANALYZE চালালে planner নতুন estimate পাবে এবং সঠিক plan বেছে নেবে।
─────────────────────────
💡 Takeaway
─────────────────────────
▸ Slow query মানেই খারাপ query না — table bloat আর stale statistics-ও দায়ী হতে পারে।
▸ VACUUM মুক্ত করে জায়গা, ANALYZE দেয় planner-কে সঠিক তথ্য — দুটো আলাদা কাজ, দুটোই দরকার।
▸ pg_stat_user_tables দিয়ে আগে diagnose করো, তারপর fix করো।
─────────────────────────
তোমার production database-এ কি কখনো autovacuum failure বা table bloat diagnose করেছ? কীভাবে ধরেছিলে? 👇