সেশন ০৭

Database Indexes - Database এর দ্রুত Data খুঁজে পাওয়ার রহস্য

এই সেশনের লক্ষ্য: একটা single database এর ভেতরে গিয়ে দেখবো, এটা কীভাবে একটা row খুঁজে বের করে। Index আসলে কী (একটা B-tree), কেন এটা read দ্রুত করে কিন্তু write এর cost বাড়ায়, composite index আর left-prefix rule কীভাবে কাজ করে, আর কখন index কোনো কাজে আসে না, এই সেশনে আমরা সেগুলো বুঝবো।

০০ যে প্রশ্নগুলোর উত্তর খুঁজবো

আগের সেশনগুলোতে আমরা database কে copy করেছি (০৩), তার সামনে cache বসিয়েছি (০৪), আর কয়েকটা machine এ ভাগ করেছি (০৫)। কিন্তু একটা machine এর ভেতরে database কীভাবে একটা row খুঁজে পায়, সেটা এখনো দেখিনি। এই সেশনে আমরা database এর ভেতরে ঢুকবো। প্রশ্নগুলোর উত্তর জানা হয়ে গেলে আপনি বুঝবেন, একটা query কীভাবে full scan থেকে binary search এ নেমে আসে।

  • ১ Database এর কাছে একটা row চাইলে, database কীভাবে সেই row টা খুঁজে পায়?
  • ২ বড় table এ একটা row খুঁজে বের করা তো slow। lookup fast করবো কীভাবে?
  • ৩ Index আসলে কী? (কোন data structure ব্যবহার হয়?)
  • ৪ INSERT, UPDATE, DELETE করলে table আর index এ কী হয়?
  • ৫ Index যদি read fast করে, তাহলে প্রতিটা column index করি না কেন?
  • ৬ একাধিক column এ filter করার জন্য কীভাবে index করবো? (composite index)
  • ৭ কখন index কাজে আসে না, বরং উল্টো ক্ষতি করে?
  • ৮ Full picture: index আগের সব কিছুর সাথে কীভাবে যুক্ত?

০১ Database এর কাছে একটা row চাইলে, database কীভাবে সেই row টা খুঁজে পায়?

সকাল দশটা। রয় একটা চায়ের দোকানে বসে আপনার application এ login করছে। সে email আর password দিলো, তারপর button চাপলো। Screen এ spinner ঘুরছে। তিন সেকেন্ড পার হলো, তারপর login হলো। একটা সামান্য login এ এত সময় লাগলো কেন?

Login এর সময় application প্রথমে email দিয়ে user কে খোঁজে। ধরুন আপনার users table এ ১ কোটি row আছে। Application তখন এই query টা পাঠায়:

SELECT * FROM users WHERE email = 'roy@example.com';

Table টা একটা বিশাল খাতার মতো। Row গুলো insertion order এ store হয়, মানে যে আগে এসেছে সে আগে (user 1, user 2, user 3…)। Email অনুযায়ী সাজানো থাকে না। তাই roy@example.com খুঁজতে database একে একে প্রতিটা row চেক করে:

Row 1: alice@example.com: মেলেনি।
Row 2: bob@example.com: মেলেনি।
...
Row 7,234,891: roy@example.com: মিলেছে।

অর্থাৎ match না পাওয়া পর্যন্ত database একটার পর একটা row পড়তেই থাকে। এটাকে বলে full table scan। Table এ m টা row থাকলে এর complexity O(m)। এর মানে খুব সোজা: row যতগুণ বাড়ে, কাজও ঠিক ততগুণ বাড়ে।

একটা lookup এর জন্যই database কে ১ কোটি পর্যন্ত row পড়তে হতে পারে। প্রতি সেকেন্ডে এমন হাজারটা query এলে system overloaded হয়ে যায়।

প্রধান সমস্যা

কোনো সাহায্য ছাড়া একটা row খোঁজা মানে শুরু থেকে এক এক করে scan করা। ছোট table এ এতে কোনো অসুবিধা নেই। কিন্তু মিলিয়ন বা বিলিয়ন row হলে database ভীষণ slow হয়ে যায়। আর এটা ঘটে প্রতিটা query তে।

০২ বড় table এ একটা row খুঁজে বের করা তো slow। lookup fast করবো কীভাবে?

একটা কাগজের phone book এর কথা ভাবুন। এতে লাখ লাখ নাম থাকে। একটা নাম খুঁজতে আপনি নিশ্চয়ই page 1 থেকে পড়া শুরু করবেন না। আপনি বইটা মাঝখানে খুলবেন। একটা নাম দেখবেন। তারপর ঠিক করবেন, আপনার নামটা এর আগে নাকি পরে। প্রতি ধাপে বাকি page এর অর্ধেক বাদ পড়ে যায়। এই পদ্ধতির নাম binary search।

Binary search কাজ করে একটাই কারণে: phone book টা sorted। নামগুলো random order এ থাকলে একটা নাম দেখে বোঝার উপায় থাকতো না, আপনার নামটা আগে নাকি পরে। তাই binary search শুধু sorted data তেই কাজ করে।

Binary search এ speed এর পার্থক্যটা বিশাল

১ কোটি row এর মধ্য থেকে একটা নাম খুঁজতে:

এই speed কে লেখা হয় O(log m)। এর মানে: data দ্বিগুণ হলে binary search এ মাত্র একটা ধাপ বাড়ে। অথচ full scan এর কাজ দ্বিগুণ হয়ে যায়। Data বাড়তে থাকলে এই পার্থক্যটাই ঠিক করে দেয়, কোন system টিকে থাকবে আর কোনটা ভেঙে পড়বে।

Insight কী পেলাম?

Data sorted থাকলেই দ্রুত খোঁজা যায়। Data sorted রাখুন, তারপর binary search ব্যবহার করুন। তাহলে খোঁজার কাজ O(m) থেকে নেমে O(log m) হয়ে যায়।

একটা সমস্যা আছে

একটা table কে physically একবারে শুধু একভাবেই sort করা যায়। Email দিয়ে sort করলে email order টা থাকে। কিন্তু তারপর username দিয়ে sort করলে email order টা নষ্ট হয়ে যায়, শুধু শেষ sort টাই টিকে থাকে। অথচ আমরা প্রায়ই অনেক column এ search করি (email, username, phone)। একটা table কে সব column অনুযায়ী একসাথে sorted রাখা যায় না।

০৩ Index আসলে কী? (কোন data structure ব্যবহার হয়?)

সমাধান হলো পুরো table কে sort না করা। তার বদলে আমরা একটা ছোট, আলাদা, sorted structure বানাই। এতে শুধু search এর column টা থাকে, আর থাকে আসল row এর দিকে একটা pointer (row টা কোথায় আছে তার ঠিকানা)।

TABLE (insertion order, unsorted):
Row 1: id:1, email: roy@example.com
Row 2: id:2, email: alice@example.com
Row 3: id:3, email: bob@example.com

INDEX on email (sorted, আলাদা structure):
alice@example.com  →  Row 2
bob@example.com    →  Row 3
roy@example.com    →  Row 1

এবার WHERE email = 'roy@example.com' খুঁজতে database তিনটা কাজ করে:

  1. Sorted index এ binary search করে। প্রায় ২৪ ধাপে roy@example.com পেয়ে যায়।
  2. Entry টা দেখায় যে row টা আছে Row 1 এ।
  3. Database সরাসরি table এর Row 1 এ চলে যায়।

Table কে physically sort না করেই আপনি binary search এর speed পেয়ে গেলেন। আর index যেহেতু আলাদা structure, তাই অনেকগুলো index বানানো যায়। প্রতিটা search এর প্রয়োজনে একটা করে:

INDEX on email    →  row এর দিকে pointer
INDEX on username →  row এর দিকে pointer
INDEX on phone    →  row এর দিকে pointer
Index কী

Index হলো এক বা একাধিক column এর একটা আলাদা, sorted copy, যেটাতে আসল row এর দিকে pointer থাকে। Table কে sort না করেই এটা একটা column এ binary search করতে দেয়। আর আপনি চাইলে অনেকগুলো index রাখতে পারেন।

এটা আসলে একটা B-tree

আসল database গুলো index কে একটা লম্বা sorted list হিসেবে রাখে না। কারণ বিশাল একটা list এর মাঝখানে কিছু insert করতে গেলে পরের সবকিছু সরাতে হতো। তাই database index রাখে একটা B-tree (বা B+ tree) হিসেবে। এটা একটা sorted tree। উপর থেকে নিচের দিকে নামলে প্রতি ধাপে খোঁজার range টা ছোট হয়ে আসে।

bob@ | roy@ root node alice@ < bob bob@ · carol@ bob … roy roy@ · zoe@ > roy
একটা B-tree: root থেকে নিচে নামলে প্রতি ধাপে খোঁজার range ছোট হয়। roy@ খুঁজতে database root দেখে ডান দিকের leaf এ নামে, আর কয়েক ধাপেই পৌঁছে যায়।

B-tree এর তিনটা গুরুত্বপূর্ণ বৈশিষ্ট্য:

কেউ “database index ব্যবহার করে” বললে প্রায় সবসময় সে একটা B-tree index এর কথাই বোঝায়। মনে রাখার ছবিটা সহজ: একটা sorted tree, যেটা ধরে নিচে নামলে দ্রুত জিনিস খুঁজে পাওয়া যায়।

০৪ INSERT, UPDATE, DELETE করলে table আর index এ কী হয়?

এবার দেখবো প্রতিটা operation এ ভেতরে আসলে কী ঘটে। আমাদের setup হলো একটা users table, যার email column এ একটা index আছে।

TABLE (insertion order):                INDEX on email (sorted):
Row 1: id:1, email: roy@example.com     alice@example.com  →  Row 2
Row 2: id:2, email: alice@example.com   bob@example.com    →  Row 3
Row 3: id:3, email: bob@example.com     roy@example.com    →  Row 1

READ (SELECT): সুবিধাটা এখানে

Query: SELECT * FROM users WHERE email = 'roy@example.com'

Index ছাড়া (full scan): worst case এ সব m টা row scan করতে হয়। Cost O(m), তাই slow।

Index সহ (B-tree binary search): database index এ roy@example.com খোঁজে (প্রায় ২৪ ধাপ)। তারপর pointer ধরে সরাসরি Row 1 এ চলে যায়। Cost O(log m), তাই fast। Index এর পুরো সুবিধা এটাই।

Index শুধু নিজের column এর read এ সাহায্য করে। যে column এ index নেই, সেখানে read করলে database আবার full scan এ ফিরে যায়।

নতুন row INSERT

id:4, email: carol@example.com insert করুন।

Step 1: table এ row লেখা (শেষে, insertion order):
Row 4: carol@example.com     ← নতুন row

Step 2: index এ সঠিক SORTED position এ insert:
alice@example.com  →  Row 2
bob@example.com    →  Row 3
carol@example.com  →  Row 4     ← sorted জায়গায় বসলো, শেষে না
roy@example.com    →  Row 1

Cost: ১টা table write, আর প্রতিটা index এ ১টা B-tree insert (সঠিক জায়গা খুঁজতে প্রায় log m ধাপ)।

Indexed column UPDATE

Row 3 এর email bob@example.com থেকে বদলে zoe@example.com করুন। Index এ এই value এর sorted position টা বদলে যায়। তাই এটা আসলে দুইটা কাজ: পুরোনো entry delete, তারপর নতুন entry insert।

Step 1: table এ value বদলান (Row 3: zoe@example.com)

Step 2: index থেকে পুরোনো entry delete (bob@example.com চলে গেলো)
Step 3: নতুন sorted position এ insert:
alice@example.com  →  Row 2
carol@example.com  →  Row 4
roy@example.com    →  Row 1
zoe@example.com    →  Row 3     ← নতুন sorted position

তাই indexed column update করা মানে একটা delete আর একটা insert। এটাই সবচেয়ে expensive operation।

Non-indexed column UPDATE

Row 1 এর last_login_time বদলান। last_login_time এ কোনো index নেই, তাই email index এ কোনো পরিবর্তন হয় না। Cost শুধু একটা table write।

Row DELETE

Row 2 (alice@example.com) delete করুন। Database table থেকে row টা সরায়, আর index থেকে তার entry টাও সরায়। Cost: ১টা table delete, আর প্রতিটা index এ ১টা B-tree delete।

সব operation একসাথে

OperationTableIndex (প্রতিটা index এ)Cost
Indexed column READpointer ধরে row এ jumpB-tree binary searchO(log m), fast (সুবিধাটা)
Non-indexed column READfull table scanindex ব্যবহার হয় নাO(m), slow
INSERTrow যোগsorted position এ ১টা inserttable write + n × O(log m)
Indexed column UPDATEvalue বদল১ delete + ১ insert (position সরে)সবচেয়ে expensive
Non-indexed column UPDATEvalue বদলকিছু নাcheap
DELETErow সরানো১ deletetable delete + n × O(log m)
Pattern টা

প্রতিটা write সেইসব index কেও বদলায়, যেগুলো বদলে যাওয়া column ধরে রাখে। INSERT আর DELETE সব index এ কাজ বাড়ায়। UPDATE কাজ বাড়ায় শুধু বদলে যাওয়া column এর index এ। আর সেখানে cost দ্বিগুণ (delete + insert), কারণ sorted position টা সরে যায়।

০৫ Index যদি read fast করে, তাহলে প্রতিটা column index করি না কেন?

কারণ index free না। n টা index থাকলে একটা row insert এর cost মোটামুটি এরকম:

১ (table write) + n × log(m)

এখানে n হলো index এর সংখ্যা, আর m হলো table এর row সংখ্যা। প্রতিটা write এর পর database কে প্রতিটা সংশ্লিষ্ট index sorted রাখতে হয়।

Index বাড়ালেপ্রভাব
Read (indexed column এ)Faster (full scan এর বদলে binary search)
Write (insert/update/delete)Slower (প্রতিটা index আপডেট করতে হয়)
Storageবেশি লাগে (প্রতিটা index একটা আলাদা structure)
নিয়মটা

যে column এ আসলে search করেন, শুধু সেগুলোই index করুন। প্রতিটা column না। প্রতিটা index এর আগে নিজেকে প্রশ্ন করুন: এই index read এ যতটা সময় বাঁচাবে, write এ তার চেয়ে কম সময় নষ্ট করবে তো? আপনার query কোন column এ খোঁজে (access pattern), সেটা দেখে index বেছে নিন।

কোন column index করবেন, তার কয়েকটা guideline:

উদাহরণ: Logs Table

একটা logs table এ সেকেন্ডে ৫০,০০০ insert হয়। কিন্তু search হয় সপ্তাহে মাত্র একবার।

সবচেয়ে common ভুল

বাস্তবে সবচেয়ে common ভুল হলো আসল query না দেখে অনুমানের উপর index বেছে নেওয়া। যে query গুলো আপনি আসলে চালান, শুধু সেগুলোর জন্যই index করুন।

০৬ একাধিক column এ filter করার জন্য কীভাবে index করবো?

দুই বা তার বেশি column একসাথে নিয়ে বানানো index কে বলে composite index (compound বা multi-column index):

INDEX on (last_name, first_name)

এই index প্রথমে প্রথম column দিয়ে sort করে। প্রথম column এর value সমান হলে দ্বিতীয় column দিয়ে sort করে, তারপর তৃতীয় দিয়ে। ঠিক একটা phone book এর মতো, যেটা আগে last_name, তারপর first_name দিয়ে সাজানো:

Rahman, Abdul
Rahman, Fatima
Rahman, Karim      ← আগে last name দিয়ে group...
Rahman, Zara          ...তারপর প্রতিটা last name এর ভেতরে first name দিয়ে sort
Roy, Amit

Left-prefix rule (যেখানে সবাই আটকায়)

ধরুন একটা (A, B, C) composite index আছে। এটা শুধু সেই query গুলোতে সাহায্য করে, যেগুলো বাম দিক থেকে টানা column এ filter করে: শুধু A, বা A+B, বা A+B+C। এটাকে বলে left prefix। যে query প্রথম column টা বাদ দেয়, সেখানে এই index কাজে আসে না।

(last_name, first_name) index দিয়ে উদাহরণ:

কেন

Index টা আগে প্রথম column দিয়ে sorted। দ্বিতীয় column টা sorted শুধু প্রথম column এর প্রতিটা group এর ভেতরে। তাই প্রথম column বাদ দিলে দ্বিতীয় column এর order এর আর কোনো অর্থ থাকে না।

দুই ধরনের সমস্যা: পার্থক্যটা গুরুত্বপূর্ণ

(country, city, age) index দিয়ে উদাহরণ:

প্রথম column ছাড়া index চলে না

প্রথম column ছাড়া index টা একদমই ব্যবহার করা যায় না, query তে পরের যত column ই থাকুক। যেমন (department, role, salary) index থাকলে শুধু (role, salary) দিয়ে filter করলে কোনো সাহায্য পাওয়া যায় না, কারণ department নেই।

Composite index এ column এর order

Column গুলো সাজান আপনার query কীভাবে খোঁজে সেই অনুযায়ী। যে column দিয়ে সবসময় filter করেন, সেটা আগে রাখুন। যেটা দিয়ে মাঝে মাঝে বাড়তি filter করেন, সেটা পরে রাখুন।

উদাহরণ: ধরুন আপনার দুইটা query আছে। একটা হলো “customer X এর সব order”, আরেকটা “একটা date range এ customer X এর order”। তাহলে index হবে (customer_id, order_date)। দুইটা query তেই customer_id আছে, তাই এটাই left prefix। কিন্তু “একটা date এ সব customer এর order” query তে এই index কাজে আসবে না। ওই query শুধু date এ filter করে, আর date left prefix না।

Covering index (এই term টা জানা দরকার)

Query তে যত column লাগে, সবগুলো index এ থাকলে database কে আর table এ যেতে হয় না। পুরো উত্তর index থেকেই দেওয়া যায়। যেমন (last_name, first_name) index আছে। এবার SELECT first_name FROM users WHERE last_name='Rahman' query টা চালালেন। এই query তে লাগে শুধু last_name আর first_name, আর দুইটাই index এ আছে। তাই database table এ না গিয়েই উত্তর দিয়ে দেয়। এটাকে বলে covering index (index টা query এর সব column “cover” করে)। Table এ যাওয়ার ধাপটা বাদ যায় বলে এটা আরো দ্রুত।

০৭ কখন index কাজে আসে না, বরং উল্টো ক্ষতি করে?

Index কাজে আসে না যখন:

Index ক্ষতি করে যখন:

অভিজ্ঞ engineer এর অভ্যাস

আগে আসল query গুলো দেখুন, তারপর সেগুলোর সাথে মিলিয়ে index করুন। যে index কোনো query ব্যবহার করে না, সেটা শুধু cost বাড়ায়, কোনো সুবিধা দেয় না।

০৮ Full picture: index আগের সব কিছুর সাথে কীভাবে যুক্ত?

আগের সেশনগুলোতে আমরা database কে copy করেছি (০৩), cache করেছি (০৪), আর ভাগ করেছি (০৫)। এসব কাজ হয়েছে database এর বাইরে, অনেক machine জুড়ে। Index থাকে একটা single database এর ভেতরে, আর সেখানে প্রতিটা query কে দ্রুত করে।

Load Balancer S2 · request ছড়ায় Cache S4 · পারলে DB একদম এড়ায় Shard Router S5 · সঠিক shard বাছে এক Shard / Database একটা single database INDEXES S7 · এই DB এর ভেতরে row দ্রুত খুঁজে পায় Table Data raw rows
একটা read প্রথমে cache এ যায় (সেশন ০৪)। Cache miss হলে read database এ পৌঁছায় (হয়তো একটা shard এ, সেশন ০৫)। সেখানে index খোঁজাকে full scan থেকে binary search এ নামিয়ে আনে। Request এর পথে index হলো একদম শেষ ধাপ, যেটা database এর ভেতরে row খোঁজা দ্রুত করে।

আগের সেশনের সাথে সম্পর্ক

Decision framework
  1. আসল query গুলো দেখুন। যে column এ filter, search বা join করেন, সেগুলো index করুন।
  2. Read-heavy table: বেশি index রাখলে লাভ হয়।
  3. Write-heavy table: যত কম index, তত ভালো।
  4. একাধিক column এ filter: composite index বানান, column গুলো left-prefix rule মেনে সাজান।
  5. প্রায়ই বদলায় এমন column: index করার আগে দুইবার ভাবুন (indexed column update এ cost দ্বিগুণ)।

০৯ মগজে প্রেশার দিন

আগে নিজে ভাবুন। তারপর দেখুন: সবাই যেভাবে ভাবে, কেন সেটা অসম্পূর্ণ, আর আসল insight টা কোথায়।

প্রশ্ন ১: Index read fast করে কিন্তু write slow করে কেন?
উত্তর দেখুন আগে নিজে ভাবুন

সবাই যেভাবে ভাবে

“Index search কে O(log m) করে। Write slow হয়, কারণ নতুন row টাকে সঠিক জায়গায় বসাতে হয়। অনেক index থাকলে cost index এর সংখ্যার সাথে বাড়ে।”

দিকটা ঠিক আছে, কিন্তু একটা জায়গা সবাই miss করে।

যে জায়গাটা আরো নিখুঁত করা দরকার

শুধু insert না। Insert, delete, আর indexed column update, তিনটাতেই index আপডেট করতে হয়। Read হলো sorted structure এ একটা O(log m) binary search। Write slow হয়, কারণ প্রতিটা নতুন row কে প্রতিটা index এর sorted position এ বসাতে হয়। তাই index যত বাড়ে, write এর cost ও তত বাড়ে।

সঠিক ভাষায়

Indexed column update সবচেয়ে expensive, কারণ এটা একটা delete আর একটা insert। Value বদলালে তার sorted position টাও সরে যায়। তাই প্রায়ই বদলায় এমন column index করলে সবচেয়ে বেশি ক্ষতি হয়।

প্রশ্ন ২: একটা orders table আছে। Common query দুইটা: (ক) customer X এর সব order, (খ) একটা date range এ customer X এর order। একটা মাত্র index দিলে কোন column এ, কোন order এ দেবেন?
উত্তর দেখুন আগে নিজে ভাবুন

সঠিক চিন্তা

Composite index (customer_id, order_date)। দুইটা query তেই customer_id আছে, তাই এটাই left prefix। আর query (খ) এর জন্য order_date সেই prefix কে আরো এক ধাপ বাড়ায়।

উল্টে দিলে কী হতো

(order_date, customer_id) দিলে query (ক) কাজ করতো না। “Customer X এর সব order” query তে কোনো date নেই। ফলে প্রথম column টাই থাকে না, আর index অকেজো হয়ে যায়। তাই query কীভাবে খোঁজে, সেই অনুযায়ী column সাজানোই সঠিক।

মূল pattern

যে column দিয়ে সবসময় filter করেন, সেটা আগে রাখুন। কোন query এই index থেকে সুবিধা পাবে, সেটা ঠিক করে left-prefix rule।

প্রশ্ন ৩: কেউ বললো, "Read slow, তাই প্রতিটা column এ একটা index দিন।" আপনি কীভাবে যুক্তি দিয়ে আপত্তি জানাবেন?
উত্তর দেখুন আগে নিজে ভাবুন

সবাই যেভাবে ভাবে

“Index এর insert, update, delete cost আছে। n টা column index করলে cost n গুণ বাড়ে। শুধু যে column এ প্রায়ই read হয়, সেগুলোই index করুন।”

মূল কথাগুলো ঠিক। কিন্তু আরো দুইটা যুক্তি যোগ করা যায়।

আরো শক্ত যুক্তি

প্রতিটা column index করলে storage নষ্ট হয়, কারণ প্রতিটা index একটা আলাদা structure। আর বেশিরভাগ index কখনো ব্যবহারই হবে না। একটা index শুধু সেই query তে সাহায্য করে, যেটা ওই column এ filter করে। তাই যে column এ কেউ search করে না, তার index শুধু write এর cost আর storage বাড়ায়, কোনো সুবিধা দেয় না।

সোজা কথা

আগে আসল query গুলো দেখুন, তারপর সেগুলোর সাথে মিলিয়ে index করুন। Table read-heavy হলে বেশি index রাখুন। Write-heavy হলে কম index রাখুন, শুধু সবচেয়ে জরুরি column এ। একাধিক column এ filter হলে composite index এর কথা ভাবুন।

১০ যে টার্মগুলো শিখলাম

টার্মমানে
Full table scanএকটা match খুঁজতে এক এক করে প্রতিটা row পড়া। O(m)।
Binary searchSorted data কে প্রতি ধাপে অর্ধেক করে value খোঁজা। O(log m)। শুধু sorted data তে কাজ করে।
Indexএকটা column এর আলাদা sorted structure, যাতে আসল row এর দিকে pointer থাকে।
B-tree (B+ tree)Index রাখার জন্য database যে sorted tree ব্যবহার করে। Lookup দ্রুত, আর insert/delete সহজ।
Composite indexএকাধিক column একসাথে নিয়ে বানানো index। আগে প্রথম column দিয়ে sorted, তারপর দ্বিতীয় দিয়ে।
Left-prefix ruleComposite index শুধু বাম দিক থেকে টানা column এর filter এ সাহায্য করে (A, A+B, A+B+C)।
Partial helpমাঝের column বাদ গেলে index আংশিক সাহায্য করে; বাদ পড়া column এর আগের অংশটুকু কাজ করে।
No help (প্রথম column নেই)প্রথম column বাদ গেলে entry point থাকে না, তাই index অকেজো।
Covering indexযে index এ query এর দরকারি সব column থাকে, তাই table এ যেতে হয় না।
Cardinalityএকটা column এ কতগুলো আলাদা value আছে। High cardinality (যেমন email) ভালো index candidate; low cardinality (যেমন gender) দুর্বল candidate।

১১ শর্ট সামারি

  1. Index হলো একটা আলাদা sorted structure (B-tree)। এটা একটা column এর read কে full scan O(m) থেকে binary search O(log m) এ নামিয়ে আনে। একটা database এর ভেতরে read দ্রুত করার সবচেয়ে বড় উপায় এটাই।
  2. Index free না। প্রতিটা insert, delete আর indexed column update এর পর প্রতিটা সংশ্লিষ্ট index কে sorted রাখতে হয়। তাই প্রতিটা column না, শুধু যে column এ আসলে query করেন সেগুলোই index করুন।
  3. একাধিক column এ filter এর জন্য composite index ব্যবহার করুন, আর column সাজান left-prefix rule মেনে। এটা বাম দিক থেকে টানা column এ সাহায্য করে (A, A+B, A+B+C)। মাঝের column বাদ গেলে আংশিক সাহায্য করে, আর প্রথম column বাদ গেলে একদমই করে না।

১২ মনে রাখুন