Thuta Learning
How Databases Work
IntermediateData & Databasesbeginner

Index နှင့် ၎င်း၏ Trade-off များ

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Index နှင့် ၎င်း၏ Trade-off များ concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • Diagram/table ကို ဖတ်ပြီး data model/schema/architecture ဘယ်လို ပုံသဏ္ဌာန်ရှိသလဲ ခြေရာခံနိုင်ရန်
  • ကိုယ့် project အတွက် database concept/system ကို ဘယ်လို အသုံးချသင့်သလဲ ရှင်းပြနိုင်ရန်

နားလည်ထားရမယ့် အချက်

Index ဆိုတာ table တစ်ခုလုံးကို scan မလုပ်ဘဲ row ကို မြန်ဆန်စွာ ရှာဖွေနိုင်ရန် database ကို ကူညီပေးတဲ့ ဖွဲ့စည်းပုံတစ်ခုပါ - စာအုပ် index ရဲ့ analogy နှင့် တူပါတယ်။

Analogy တစ်ခုသာဖြစ်ကြောင်း သတိထားပါ

Database index ဟာ engine က အတွင်းပိုင်းမှာ ထိန်းသိမ်းထားတဲ့ သီးခြား data structure ဖြစ်ပြီး စာအုပ် page list နှင့် စက်ပိုင်းအရ ကွာခြားပါတယ်။

Index တွေဟာ trade-off တစ်ခုပါ - read ကို မြန်စေပေမယ့် storage ပိုကုန်ပြီး write တိုင်းက index ကိုပါ update လုပ်ရလို့ write ပိုနှေးသွားစေပါတယ်။

  • WHERE filter မှာ မကြာခဏ သုံးသော column
  • join မှာ သုံးသော column
  • ORDER BY sort မှာ သုံးသော column
  • unique lookup လိုအပ်သော column (ဥပမာ email)
  • column တိုင်းကို index မလုပ်ပါနှင့်

Unique index က row နှစ်ခုက value မတူရအောင် အတင်းဆောင်ပြီး lookup ကိုလည်း မြန်စေပါတယ်။ Composite index က column များစွာကို လွှမ်းခြုံပြီး column order က query ဘယ်ခုကို ကူညီနိုင်လဲကို ပြောင်းလဲစေပါတယ်။

N+1 query problem - post 100 ခုကို fetch ပြီး author 100 ခုအတွက် query သီးခြား 100 ခု run လုပ်တာဟာ join တစ်ခုနှင့် တစ်ခါတည်း fetch လုပ်တာထက် များစွာ ပိုနှေးတတ်ပါတယ်။ SQL/PostgreSQL tutorial မှာ index syntax နှင့် EXPLAIN ကို လက်တွေ့ လေ့လာနိုင်ပါတယ်။

Index
Table ကို scan မလုပ်ဘဲ column တစ်ခု (သို့မဟုတ် ပေါင်းစပ်) အပေါ်အခြေခံပြီး row ကို မြန်ဆန်စွာ ရှာဖွေနိုင်ရန် database က ထိန်းသိမ်းထားသော ခွဲထားသော data structure တစ်ခု။
N+1 Query Problem
List တစ်ခု (post 100) ကို fetch လုပ်ပြီးနောက် item တစ်ခုချင်းစီအတွက် ဆက်စပ် data (author) ကို သီးခြား query တစ်ခုစီ run လုပ်ခြင်းကြောင့် join/batch တစ်ခုထက် များစွာ ပိုနှေးသွားစေသော pattern။
text
INDEX LOOKUP VS FULL SCAN, AND N+1
----------------------------------
WITHOUT INDEX (linear scan)
row1 -> row2 -> row3 -> ... -> row9999 -> MATCH
checks potentially every row until found

WITH INDEX (direct lookup)
index[key] -> MATCH
one direct jump to the row, like a book's index

N+1 PROBLEM
1 query:     SELECT * FROM posts;          (100 rows)
100 queries: SELECT * FROM authors WHERE id=? (x100)
BETTER: 1 query with a JOIN, or 1 batched IN (...)

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

Query တစ်ခုက slow ဖြစ်ပြီး column တူတူပေါ် ထပ်ခါထပ်ခါ filter/join/sort လုပ်နေတာ သတိထားမိမှသာ index ထည့်ပါ - column တိုင်းအပေါ် ကြိုတင် ထည့်တာ မဟုတ်ပါ။

PostgreSQL ရဲ့ EXPLAIN လိုမျိုး tool တွေက index ဘယ်ခုရှိလဲ၊ query planner က ဘယ်လို သုံးနေလဲ ကြည့်ဖို့အတွက်ပါ။

Loop ထဲက N+1 pattern ကို သတိထားပါ - item တစ်ခုချင်းစီအတွက် query တစ်ခုစီ run နေရင် join သို့မဟုတ် batch query တစ်ခုအဖြစ် ပြောင်းသင့်ပါတယ်။

Index ထည့်ခင် write overhead က table ရဲ့ read/write ratio နှင့် ယှဉ်ရင် ထိုက်တန်ပါသလားလို့ မေးကြည့်ပါ။ အောက်က runnable ဥပမာက index ပါ/မပါ ရှာဖွေမှု ကွာခြားချက်ကို ပြသပါတယ်။

အတူတူ စမ်းရေးကြည့်မယ်

javascript
function linearSearch(rows, field, value) {
  let comparisons = 0;
  let found = null;
  for (const r of rows) {
    comparisons++;
    if (r[field] === value) {
      found = r;
      break;
    }
  }
  return { found, comparisons };
}

function buildIndex(rows, field) {
  const map = new Map();
  for (const r of rows) map.set(r[field], r);
  return map;
}

function indexedSearch(index, value) {
  return { found: index.get(value) || null, comparisons: 1 };
}

const bigTable = [];
for (let i = 1; i <= 5000; i++) {
  bigTable.push({ id: i, email: `user${i}@example.com` });
}
const target = "user4999@example.com";

const withoutIndex = linearSearch(bigTable, "email", target);
const emailIndex = buildIndex(bigTable, "email");
const withIndex = indexedSearch(emailIndex, target);

console.log("Without index comparisons:", withoutIndex.comparisons);
console.log("With index comparisons:", withIndex.comparisons);
You should see
Without index comparisons: 4999
With index comparisons: 1

Row 5000 ခုထဲမှာ 4999 ခုမြောက် row ကို ရှာနေလို့ linear scan က comparison 4999 ကြိမ် လိုအပ်ပြီး Map ကို သုံးထားတဲ့ index ကတော့ တစ်ကြိမ်တည်းနှင့် တွေ့ပါတယ်။

၅ မိနစ် စမ်းကြည့်

linearSearch/indexedSearch ကို rows 50000 ခုနှင့် ပြန်စမ်းကြည့်ပြီး comparison count ကွာခြားချက်ကို ရေးထုတ်ပါ။ table အရွယ်အစားနှင့်အမျှ ကွာခြားချက်က ဘယ်လိုပြောင်းလဲသွားလဲ ကြည့်ပါ။

သတိလေးတစ်ချက်

Column တိုင်းကို "ပိုမြန်အောင်" ဆိုပြီး index လုပ်လိုက်ပြီး write performance ကို ထည့်မတွက်ဘဲ ချန်ထားခြင်း

Loop ထဲမှာ item တစ်ခုချင်းစီအတွက် query သီးခြား run နေတာကို N+1 problem ဟု မသိဘဲ ထားခြင်း

Wikipedia: Database indexHow Databases Work

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • Column တိုင်းကို "ပိုမြန်အောင်" ဆိုပြီး index လုပ်လိုက်ပြီး write performance ကို ထည့်မတွက်ဘဲ ချန်ထားခြင်း
  • Loop ထဲမှာ item တစ်ခုချင်းစီအတွက် query သီးခြား run နေတာကို N+1 problem ဟု မသိဘဲ ထားခြင်း
  • ဒီ course က database concept/landscape ကို framework-neutral level မှာသာ သင်ပေးပါတယ် — SQL syntax, PostgreSQL, MongoDB, Redis ကို နက်နက်ရှိုင်းရှိုင်း လေ့လာချင်ရင် SQL, PostgreSQL, MongoDB, Redis tutorial တွေဆီ ဆက်သွားပါ။

လေ့ကျင့်ခန်း

linearSearch/indexedSearch ကို rows 50000 ခုနှင့် ပြန်စမ်းကြည့်ပြီး comparison count ကွာခြားချက်ကို ရေးထုတ်ပါ။ table အရွယ်အစားနှင့်အမျှ ကွာခြားချက်က ဘယ်လိုပြောင်းလဲသွားလဲ ကြည့်ပါ။

You'll know it worked when: Without index comparisons: 4999 With index comparisons: 1 Row 5000 ခုထဲမှာ 4999 ခုမြောက် row ကို ရှာနေလို့ linear scan က comparison 4999 ကြိမ် လိုအပ်ပြီး Map ကို သုံးထားတဲ့ index ကတော့ တစ်ကြိမ်တည်းနှင့် တွေ့ပါတယ်။

Index နှင့် ၎င်း၏ Trade-off များ | Thuta Learning