Database IndexB-TreeComposite IndexHash IndexPostgreSQLBackend Engineering

Day 10 — Database Index- একটা দুইধারী তলোয়ার

June 16, 20265 min read30 Days Of Backend Engineering

আয়নাল সাহেব একজন দক্ষ reader। প্রচুর বই পড়েন। মোটামুটি ১০০০-এর উপরে বই আছে। In fact উনার একটা dedicated reading room আছে। সেখানে তিনি পড়াশোনা করেন। তিনি একটু রগচটা, অল্পতেই রেগে যান। এই কারণে প্রায়ই তিনি রাগারাগি করে বাড়ি গরম করে তোলেন। এরকম পরিস্থিতি দেখার পর উনার স্ত্রী, তাদের নাতি নয়নকে (grandchild) এই বিষয়টা জানান। নয়ন একজন engineer ছিল। নয়ন আসলো, এসে সবকিছু পর্যবেক্ষণ করলো। এর আসল problem-টা বুঝতে পারলো। আয়নাল সাহেবের বই খুঁজতে অনেক problem হয়, খুঁজে পান না।

পর্যবেক্ষণ করার পর তার কয়েকটা idea মাথায় আসলো। 1st idea হচ্ছে, সারিবদ্ধভাবে নামের word-এর ওপর base করে বইগুলো সাজিয়ে রাখা যেতে পারে। তাহলে problem কিছুটা solve হবে। কিন্তু পরক্ষণেই মাথায় আসলো, যদি জায়গা শেষ হয়ে যায় বা same word-এর বই অনেক আসে, তখন তো আর হবে না।

সে আরও কিছুক্ষণ ভাবলো, ভাবার পর এই idea-টাকেই একটু modify করলো। সবগুলো সারিবদ্ধ করার বদলে, বাংলা অক্ষরের কয়েকটা range বানালো for example 'অ' থেকে 'এ' পর্যন্ত, আবার 'ক' থেকে 'ছ' পর্যন্ত, এভাবে। যখনই এই অক্ষরের word-এর বই আসবে তখনই এই range-এর ভেতরে যাবে। এবং finally আরেকটা list করলো যেখানে এই range-গুলোর location বা bookshelf-এর কোথায় আছে সেটা সেখানে লিখে রাখলো। ব্যাস, কাজ শেষ।

এই কাজ করার পর আয়নাল সাহেবের রাগের পরিমাণ কমে গেছে। তবে তিনি কিন্তু এখনো রাগেন, তবে একটু কম।

ওপরের problem-টা, যে way-তে solve করা হয়েছে, সেটা হলো Database-এর ভাষায় Indexing


Index আসলে কী?

Database index হলো মূলত একটা আলাদা data structure যেটা original table-এর পাশাপাশি maintain করা হয়।

এখানে মূলত data-এর একটা list বা table maintain করা হয় যেখানে, data-র actual location কোথায় সেটা লিখে রাখা হয়। আর যখন query করা হয় তখন এই list-কে use করে দ্রুত query করা possible হয়।


Indexing ছাড়া Database কীভাবে কাজ করে?

Indexing-টা database-এ mandatory না। একটা জিনিস চিন্তা করুন, আপনি কিন্তু একটা বইয়ের সূচিপত্র ছাড়াও কিন্তু বইটা পড়তে পারবেন। সেক্ষেত্রে আপনাকে first page থেকে সবকিছুই পড়তে হবে। কোনো নির্দিষ্ট page খুঁজতে হলেও page by page খুঁজতে হবে।

Database-এর ক্ষেত্রেও same জিনিস। Database data store করার জন্য file system use করে। তাই data সবকিছুই save করা থাকে। সেই save করা data normal ভাবেই use করা যায়। কিন্তু কোনো data খুঁজতে গেলে সেখানে প্রত্যেকটা data-কে check করে তারপর খুঁজতে হয়।

Hopefully বুঝতে পারছেন যে, indexing ছাড়াই database কাজ করতে পারে।


Indexing-এর ম্যাজিক

আপনি যদি JSC বা SSC বা HSC board exam দিয়ে থাকেন তাহলে আপনাদের একটা registration number দেয়া হয়ে থাকে। এবং এই registration number-টা কিন্তু unique হয়। আপনি বাদে অন্য কেউ use করতে পারবেজীবী না।

এখন আপনার এই registration number দিয়ে আপনার information খুঁজে বের করতে হবে। তাহলে প্রত্যেকটা data check করে করে কিন্তু আপনার information-এর কাছে পৌঁছাবে।

এখন এই searching যদি 10M student-এর হয় তাহলে কত সময় লাগবে? 1B হলে কত সময় লাগবে? এরপরে যদি 10B হয়? আর যদি 100B হয় তখন কত সময় লাগবে খুঁজে বের করতে? এখানে student-এর সংখ্যা যত বাড়বে, searching-এর time-ও তো বাড়বে।

এটাই যদি হয়, তাহলে আমার registration number-টা unique হওয়ার খুব বেশি সুবিধা করতে পারছি না। সব data তো মিলিয়ে মিলিয়ে দেখতে হচ্ছে।

Indexing কীভাবে করা হয় সেটা তো বুঝে গেছেন already। Indexing করার মাধ্যমে এই registration number-এর student-এর data কোথায় আছে সেটা সুন্দর করে store করে রাখা হয়। যখনই এই registration number দিয়ে search করবো তখনই কয়েক second-এ খুঁজে এনে দিবে। এখানে আপনার data-র size increase হলেও খুব বেশি time লাগবে না।


**ওভার-ইনডেক্সিং: যেখানে ক্যাচালটা লাগে!**

বাংলা ভাষাতে একটা প্রবাদ আছে, "অতি ভক্তি চোরের লক্ষণ"। এই কথার মর্মার্থ হচ্ছে, যে ব্যক্তি প্রয়োজনের তুলনায় বেশি ভক্তি করে তার ভেতরে ঘাপলা আছে। Indexing-এর বেলাতেও এটা কিছুটা খাটে। আপনি যদি indexing-কে বেশি ভক্তি (use) করেন, তাহলে indexing আপনাকে ডোবাবে এটা sure থাকেন। কেন বলছি এই কথা?

মনে করুন, আপনি indexing-এর usage আর power দেখে পুরো impress হয়ে গেছেন। এই চক্করে একটা table-এর সব column-কে indexing করে ফেললেন। আপনি তো সেই রকমের আশাবাদী যে আপনার application আকাশে উড়বে। Speed আর performance সেই আকারে দিবে।

কিন্তু হলো এর বিপরীত, আগের তুলনায় এখন application-এর performance down হয়ে গেছে। Speed আগের থেকেও কমে গেছে।

এখন আপনার কাছে প্রশ্ন, data যদি আরও বাড়ে, তাহলে এই performance + speed কমবে নাকি বাড়বে?

Answer হচ্ছে, speed + performance কমে যাবে।

এখন আপনি বলবেন, "কেন স্পিড কমে যায়?"

Indexing ডেটা Retrieve (বা Read) করার জন্য বস হলেও, Write অপারেশনের সময় এটা রীতিমতো একটা পেইন। যখনই আপনি Database-এ নতুন কোনো ডেটা Insert বা Update করবেন, তখন শুধু ওই নির্দিষ্ট রো আপডেট করলেই হয় না; বরং আপনার ইনডেক্স করা সবগুলো কলামের B-Tree আপডেট করতে হয়। এখানে মূলত ওই সমস্ত B-tree গুলা update হবে যেই column এর ভ্যালু update হয়েছে, বাকি B-tree গুলা intact-ই থাকবে।

আপনার ডেটাবেসে মিলিয়ন মিলিয়ন ডেটা আছে। আপনি ছোট্ট একটা ভ্যালু আপডেট করবেন, কিন্তু ব্যাকগ্রাউন্ডে ইনডেক্সিংয়ের পুরো স্ট্রাকচার আপডেট হচ্ছে। যতক্ষণ না এই B-Tree আপডেট শেষ হচ্ছে, ততক্ষণ কিন্তু ডেটা Write হবে না, আর সার্ভারও রেসপন্স করবে না। এই সময়ে Database Connection pool রিলিজ হবে না। ফলে যখনই একসাথে অনেক ইউজার (Concurrent users) হিট করবে, Database তার লিমিট ক্রস করে ফেলবে আর সিস্টেম ডাউন বা স্লো হয়ে যাবে।


Indexing কীভাবে করবো?

Indexing-এর কোনো বাঁধা ধরা rules নেই। এই জন্য এটা pain দেয়। কিন্তু কিছু জিনিস মাথায় রাখলে indexing জিনিসটা easy হয়ে যায়। Table-এর column-এর ক্ষেত্রে নিচের বিষয়গুলো follow করা যেতে পারে:

  • SQL query-তে যেই column সব থেকে বেশি use করা হয়।
  • কোনো unique column-এর জন্য।
  • Searching + sorting-এর জন্য যেই column use হয়।
এগুলো basic বিষয়, আপনি চাইলে আপনার মতো করে use করতে পারেন।

Indexing করার সময় নিচের বিষয়টা এড়িয়ে চললে ভালো:

  • Small table — ১০০০ row-এর table full scan সব সময়ই দ্রুত।
  • Low cardinality column — যেমন gender column-এ মাত্র ২-৩টা unique value। Index এখানে benefit দেয় না।
  • Function-এর ভেতর columnWHERE LOWER(email) = 'test@gmail.com' এখানে email-এর index কাজ করবে না।

বটম লাইন

এতক্ষণে বুঝে গেছেন, title-এ "একটা দুইধারী তলোয়ার" কেন বলেছি। বুঝে-শুনে, শুধু দরকারি জায়গায় ইউজ করলে এটা লাইফ সেভার, আর না বুঝে সব জায়গায় মেরে দিলে খবর আছে!