আগের Beyond the Basics lesson সংক্ষেপে EXPLAIN আর index পরিচয় করিয়েছে। এই lesson একটা ধীর query-কে আসলে দ্রুত বানানোর জন্য একটা পূর্ণ, practical technique-এর সেট।
EXPLAIN দেখায় database আসলে একটা query কীভাবে চালানোর পরিকল্পনা করে — এটা কোন index ব্যবহার করবে, কোন ক্রমে প্রতিটা table স্পর্শ করবে, আর প্রতিটা step-এ মোটামুটি কতগুলো row আশা করে।
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;
-- একটা "Seq Scan" (sequential scan) মানে এটা প্রতিটা row পড়ছে —
-- সাধারণত customer_id-তে একটা useful index নেই এমন একটা চিহ্ন
-- একটা "Index Scan" মানে এটা একটা index খুঁজে ব্যবহার করেছে — লক্ষ্যএকটা index একটা column-এর মান দিয়ে row খুঁজে বের করা দ্রুত করে, কিছু অতিরিক্ত storage আর সামান্য ধীর write-এর খরচে। Index করার যোগ্য column সেগুলো যা আসলে filter বা join করতে ব্যবহৃত হয় — প্রতিটা column না।
-- এই WHERE clause ক্রমাগত চললে আর ধীর হলে, এই index সম্ভবত সাহায্য করে:
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
SELECT * FROM orders WHERE customer_id = 42;Common Mistake
"just in case" প্রতিটা column index করা backfire করে — প্রতিটা index সেই table-এর প্রতিটা INSERT/UPDATE/DELETE ধীর করে, কারণ index নিজেও আপডেট করা দরকার। Query আসলে যা filter বা join করে তা index করুন, সবকিছু না।
Outer query-র প্রতিটা row-এর জন্য আবার চলা একটা subquery (আগের Subqueries lesson থেকে একটা correlated subquery) প্রায়ই একটা JOIN হিসেবে পুনর্লিখন করা যায়, যা database সাধারণত আরো efficiently plan করতে পারে।
-- ধীর — subquery products-এর প্রতি row-এ একবার চলে
SELECT name FROM products p
WHERE (SELECT COUNT(*) FROM order_items oi WHERE oi.product_id = p.id) > 0;
-- প্রায়ই দ্রুত — join হিসেবে পুনর্লিখন করা
SELECT DISTINCT p.name
FROM products p
JOIN order_items oi ON oi.product_id = p.id;প্রতিটা column-এর বদলে শুধু আসলে দরকারি column চাওয়া database-কে যা পড়তে আর পাঠাতে হয় তা কমায় — একটা বড় table-এ যা অনেক জমা হয় এমন একটা ছোট habit।
-- শুধু name দরকার হলে অপচয়
SELECT * FROM products WHERE category = 'electronics';
-- ভালো
SELECT name FROM products WHERE category = 'electronics';| Technique | যা বাঁচায় |
|---|---|
| সঠিক column index করা | একটা মিল খুঁজতে প্রতিটা row scan করা এড়ায় |
| Indexed column-এ join করা | join-এর একদিকে row-ধরে-ধরে scan এড়ায় |
| Join করার আগে filter করা | কতটা data একসাথে করা হয় তা কমায় |
| Correlated subquery-কে join হিসেবে পুনর্লিখন | একই subquery outer row-এ একবার আবার চালানো এড়ায় |
| শুধু দরকারি column select করা | পড়া আর transfer হওয়া data কমায় |