Query optimization নিয়ে বাংলায় একটা টিউটোরিয়াল লিখে দাও
ডাটাবেসের সাথে কাজ করার সময় ধীরগতির কোয়েরি সবচেয়ে বড় মাথাব্যথার কারণ। একটি খারাপভাবে লেখা SQL কোয়েরি সার্ভারের CPU এবং মেমরি গ্রাস করে, অ্যাপ্লিকেশনকে ধীর করে দেয়, এবং শেষ পর্যন্ত ইউজার এক্সপেরিয়েন্স নষ্ট করে। এই টিউটোরিয়ালে আমরা শিখব কীভাবে SQL কোয়েরিগুলোকে বিশ্লেষণ করে দ্রুততর করা যায়, এবং কোন কৌশলগুলো ব্যবহার করলে ডাটাবেসের পারফরম্যান্স নাটকীয়ভাবে বেড়ে যায়। আমরা বেসিক ইন্ডেক্সিং থেকে শুরু করে অ্যাডভান্সড টেকনিক যেমন EXPLAIN প্ল্যান বিশ্লেষণ পর্যন্ত কভার করব।
কেন Query Optimization গুরুত্বপূর্ণ?
প্রতিটি ডাটাবেস অপারেশনের একটি খরচ আছে — তা সে ডিস্ক I/O হোক, মেমরি অ্যাক্সেস হোক, অথবা CPU সাইকেল। একটি অপ্টিমাইজড কোয়েরি এই খরচগুলোকে ন্যূনতম করে। ধরা যাক, আপনার একটি orders টেবিলে ১০ লাখ রেকর্ড আছে। যদি আপনি WHERE ক্লজে ইন্ডেক্স না ব্যবহার করেন, তাহলে ডাটাবেসকে পুরো টেবিল স্ক্যান করতে হবে (Full Table Scan), যা সেকেন্ড বা মিনিট সময় নিতে পারে। অন্যদিকে, সঠিক ইন্ডেক্স থাকলে সেই কোয়েরি মিলিসেকেন্ডে শেষ হয়।
অপ্টিমাইজেশন শুধু গতি বাড়ায় না, এটি সার্ভারের উপর লোড কমিয়ে দেয়। এর ফলে:
- স্কেলেবিলিটি বাড়ে: একই সার্ভারে বেশি ইউজার সাপোর্ট করতে পারেন।
- কস্ট কমে: ক্লাউড ডাটাবেসে কম CPU/IO ইউনিট ব্যবহার হয়।
- ডেটা কনসিস্টেন্সি রক্ষা পায়: দীর্ঘক্ষণ ধরে চলা কোয়েরি লক (Lock) তৈরি করে, যা অন্য ট্রানজেকশনকে ব্লক করতে পারে।
অপ্টিমাইজেশনের মূল কৌশল
প্রথম ধাপ হলো ইন্ডেক্সিং বোঝা। ইন্ডেক্স একটি বইয়ের সূচিপত্রের মতো — এটি ডাটাবেসকে বলে দেয় নির্দিষ্ট ডাটা কোথায় আছে, ফলে পুরো বই পড়তে হয় না। তবে সব ক্ষেত্রে ইন্ডেক্স ভালো নয়; অনেক বেশি ইন্ডেক্স INSERT এবং UPDATE কে ধীর করে দেয়।
নিচে কিছু মৌলিক কৌশল দেওয়া হলো:
- সিলেক্টিভ ইন্ডেক্স ব্যবহার: যেসব কলামে ডাটার বৈচিত্র্য (Cardinality) বেশি, সেগুলোতে ইন্ডেক্স দিন। যেমন
statusকলামে যদি মাত্র ২টি ভ্যালু (Active/Inactive) থাকে, সেটাতে ইন্ডেক্স তেমন কাজে দেবে না। - কম্পোজিট ইন্ডেক্স: যখন একাধিক কলামে
WHEREক্লজ ব্যবহার করেন, তখন একটি কম্পোজিট ইন্ডেক্স তৈরি করুন। কলামের অর্ডার গুরুত্বপূর্ণ — সবচেয়ে বেশি ফিল্টারিং করা কলামটি প্রথমে রাখুন। SELECT *এড়িয়ে চলুন: আপনার প্রয়োজনীয় কলামগুলোই শুধু সিলেক্ট করুন। অপ্রয়োজনীয় কলাম আনলে ডাটাবেসকে বেশি I/O করতে হয়।EXPLAINব্যবহার: আপনার ডাটাবেসের জন্যEXPLAINবাEXPLAIN ANALYZEকমান্ড ব্যবহার করে দেখুন কোয়েরিটি কীভাবে এক্সিকিউট হচ্ছে। এটি দেখাবে কোথায় Full Table Scan হচ্ছে, কোথায় ইন্ডেক্স ব্যবহার হচ্ছে না।
উদাহরণ: একটি ধীরগতির কোয়েরি ফিক্স করা
ধরুন, আপনি ব্যবহারকারীদের শেষ লগইনের ভিত্তিতে ফিল্টার করতে চান:
-- ধীরগতির কোয়েরি (কোনো ইন্ডেক্স নেই)
SELECT * FROM users WHERE last_login > '2023-01-01';
এই কোয়েরি পুরো users টেবিল স্ক্যান করবে। অপ্টিমাইজড ভার্সন:
-- প্রথমে ইন্ডেক্স তৈরি করুন
CREATE INDEX idx_last_login ON users(last_login);
-- এখন দ্রুত কোয়েরি
SELECT id, username, email FROM users WHERE last_login > '2023-01-01';
এখানে আমরা শুধু প্রয়োজনীয় কলাম নিচ্ছি এবং last_login কলামে ইন্ডেক্স তৈরি করেছি। ফলে ডাটাবেস শুধু ইন্ডেক্সের মাধ্যমে প্রাসঙ্গিক রো খুঁজে বের করবে।
JOIN এবং সাবকোয়েরি অপ্টিমাইজেশন
JOIN অপারেশন সবচেয়ে বেশি পারফরম্যান্স ইস্যু তৈরি করে। একটি সাধারণ ভুল হলো বড় টেবিলের সাথে ছোট টেবিলের ভুল অর্ডারে JOIN করা। ডাটাবেস অপ্টিমাইজার সাধারণত নিজেই সঠিক অর্ডার বেছে নেয়, কিন্তু কিছু ক্ষেত্রে আমাদের সাহায্য করতে হয়।
মনে রাখার বিষয়:
- ড্রাইভিং টেবিল ছোট রাখুন: যে টেবিলে সবচেয়ে কম রো রিটার্ন হবে, সেটি
JOIN-এর বাম পাশে রাখুন (যদি আপনার ডাটাবেসের অপ্টিমাইজার না পারে)। - সাবকোয়েরির পরিবর্তে
JOINব্যবহার করুন: অনেক সময় সাবকোয়েরি (Subquery) ধীর হয়। নিচের উদাহরণটি দেখুন:
-- ধীরগতির সাবকোয়েরি
SELECT * FROM orders
WHERE customer_id IN (SELECT id FROM customers WHERE status = 'active');
-- দ্রুততর JOIN
SELECT o.* FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE c.status = 'active';
দ্বিতীয় কোয়েরিটি সাধারণত দ্রুত হয়, কারণ ডাটাবেস ইন্ডেক্স ব্যবহার করে সহজেই ডাটা ম্যাচ করতে পারে। তবে সব সময় এটি সত্য নয়; আপনার ডাটাবেসের EXPLAIN প্ল্যান চেক করা জরুরি।
বেস্ট প্র্যাকটিস এবং সাধারণ ভুল
অপ্টিমাইজেশনের শেষ ধাপ হলো নিয়মিত মনিটরিং এবং রিফ্যাক্টরিং। একটি কোয়েরি আজ দ্রুত থাকলেও, ডাটা বাড়ার সাথে সাথে ধীর হয়ে যেতে পারে।
নিচের টিপসগুলো ফলো করুন:
LIKEঅপারেটর সাবধানে ব্যবহার করুন:LIKE '%keyword'ইন্ডেক্স ব্যবহার করতে পারে না। যদি সম্ভব হয়,LIKE 'keyword%'ব্যবহার করুন অথবা ফুল-টেক্সট সার্চ ইঞ্জিন (যেমন Elasticsearch) বিবেচনা করুন।ORএর পরিবর্তেUNION ALL: যদিORব্যবহার করে একাধিক ভিন্ন কলাম ফিল্টার করেন, ডাটাবেস ইন্ডেক্স ব্যবহার করতে পারে না। সেক্ষেত্রেUNION ALLবেশি কার্যকর।- পেজিনেশন অপ্টিমাইজ করুন:
OFFSETবড় সংখ্যা হলে ধীর হয়।WHERE id > last_seen_idপদ্ধতি ব্যবহার করে পেজিনেশন করুন (Keyset Pagination)। - ডাটা টাইপ ম্যাচিং:
WHERE varchar_column = 123লিখলে ডাটাবেসকে ইমপ্লিসিট কনভার্শন করতে হয়, যা ইন্ডেক্স ব্যবহারে বাধা দেয়। সবসময় সঠিক ডাটা টাইপ ব্যবহার করুন।
সংক্ষেপে, query optimization একটি চলমান প্রক্রিয়া। প্রথমে EXPLAIN দিয়ে বোতলনেক চিহ্নিত করুন, তারপর ইন্ডেক্স, JOIN অর্ডার, এবং সঠিক SQL প্যাটার্ন প্রয়োগ করে কোয়েরি দ্রুততর করুন। নিয়মিত পারফরম্যান্স টেস্টিং এবং ডাটা গ্রোথের সাথে সাথে ইন্ডেক্স রিভিউ করা আপনার ডাটাবেসকে সুস্থ রাখবে।