SevyDevy

Module 4 · Storing Data That Keeps Growing · Lesson 15 of 35

What is indexing in DBMS? Finding one row in ten lakh

12 minFree System design course · Beginner to intermediateLesson 4.2By Saket Bhatnagar

Researched and drafted with AI, reviewed and edited by Saket Bhatnagar.

In short

  • What is indexing in DBMS? It is building a sorted helper list, an index, so the database jumps to the rows you want instead of reading them all.
  • Think of the index at the back of a thick textbook: find the word, read the page number, jump.
  • Reads get much faster, but every write must also change each index, so index only the columns your app searches by.
Soon

Video lesson · coming soon

What is indexing in DBMS? One row in ten lakh

Lala, your AI mentor, will walk you through this lesson in a short animated video. Until then, everything is here to read and try.

  1. 01 Four seconds for My bookings
  2. 02 The index at the back of the book
  3. 03 Root, branch, leaf
  4. 04 Scan, index, then the cost
  5. 05 Arjun keeps three
  6. 06 Practise reading a slow query

SeatJaldi is safe now: bookings save all or nothing, and Meera Kulkarni has raised a ₹2 crore seed round. This season’s bookings table, a big spreadsheet with one row per booking, has grown to 10 lakh rows.

On a busy sale afternoon, before an investor demo, Meera opens “My bookings”. A spinner turns for 4 seconds. A match page, from the same database, loads at once.

Arjun Nair finds the query, the question the app asks the database. “My bookings” asks SELECT * FROM bookings WHERE user_id = 812: every booking of user 812. The match page asks by id, the number that names each row. Both want a few rows out of ten lakh. Why is one instant and the other 4 seconds?

What is indexing in DBMS?

An index is a sorted helper list that lets the database jump straight to the rows you ask for, instead of reading the whole table. Each detail of a booking, such as user_id, is a column.

The database keeps a table in pages, small blocks of about 8 KB (roughly 8,000 letters of data). With no index on user_id, it must read every page and check every row.

Full scan or index look-up, same answer

No index: about 12,000 pages read for three rows. With one: about 6.

Diagram connections:

  • Same question to Full table scan (No index)
  • Same question to Index look-up (With index)
  • Full table scan to Three bookings (Slow)
  • Index look-up to Three bookings (Fast)
  • Same question: Find the bookings of user 812.
  • Full table scan: Reads about 12,000 pages (assumed sizes).
  • Index look-up: Reads about 6 pages: 3 in the index, up to 3 in the table.
  • Three bookings: Same answer, less work.
  • An index is the back-of-the-book index: fast reads, paid for on every write.
  • It is sorted and stores where rows live, so the database narrows and jumps.

You have seen this when a ticket app finds a booking by its id at once, but pauses on a phone number search. Only the id had an index.

Or when a ticket app crawls at “Confirm booking” as a big sale opens. Each booking was also written into many helper lists.

How does a B-tree index find one row among ten lakh?

A B-tree is a tree of sorted pages, and each step down narrows the search, so a few page reads find the row. PostgreSQL, a popular database, builds one whenever you ask for an index without naming a type.

Mridul’s book index has thumb tabs: a letter, then a group of words, then the word. A B-tree is the same: a root page on top, branch pages below, and leaf pages holding the row locations.

How a B-tree finds user 812

Root page, one branch, one leaf, then the row locations: three small steps instead of reading ten lakh rows.

Diagram connections:

  • Look up user 812 to Root page (Start)
  • Root page to Branch page (Pick branch)
  • Branch page to Leaf page (Pick leaf)
  • Leaf page to Bookings table (Row locations)
  • Look up user 812: Which bookings belong to user_id 812?
  • Root page: 812 is between 500 and 1000: go to branch page 2.
  • Branch page: 812 is between 800 and 900: go to leaf page 17.
  • Leaf page: Lists where user 812’s three rows live.
  • Bookings table: Only the three matching rows are read.
Try it yourselfFrom a full scan to an index look-up, and what it costsOne question with and without an index, then the cost on writes.

When should you not add an index?

Skip an index when the column is rarely searched, the table is small, or it is written far more than read. A textbook indexed on every word would have an index as thick as the book.

Index it or not? SeatJaldi examples
Column or tableIndex it?Why
user_id, used by “My bookings”YesA frequent question on a big table
A venues table with 40 rowsNoReading 40 rows is already instant
amount_rupees, which no screen searchesNoEvery write pays; no read gains
A log of every tap, written all day, read once a nightUsually noWrites far outnumber reads

What just happened? Four of Arjun’s six extra indexes, on seat_code, status, created_at and amount_rupees, served no screen on their own. They only slowed the noon sale, so he dropped them.

What does an index cost, and how do engineers choose one?

An index trades write work and disk space for read speed. Engineers pick indexes from the real queries, then check with EXPLAIN. It shows the plan from the planner, the part of the database that decides how to run a query.

Why so few steps? Assume an index page holds about 500 entries. Ten lakh entries fill 1,000,000 / 500 = 2,000 leaf pages, 4 branch pages and one root: 3 levels. Three levels reach 500 x 500 x 500 = 12.5 crore entries, so even 10 crore rows need about 3 reads.

The table is about 12,000 pages and the look-up reads about 6: 2,000 times fewer. The clock showed 4,000 ms to 15 ms, about 267 times. Pages read in order cost less than scattered jumps, and many were already in memory.

  • B-tree, the default: equals, less than, more than and the like, BETWEEN, IN and sorted order. Also LIKE 'A1%', with a special index under some settings.
  • Hash: a 32-bit hash of each value, so only “equals”.
  • GIN: one entry per part of a value, such as each word, for searching inside values.
  • BRIN: the smallest and largest value per run of pages; tiny, for a column like created_at that follows arrival order.

A two-column index is sorted by the first column, then the second. An index on (match_id, status) serves WHERE match_id = 42 AND status = 'sold', and WHERE match_id = 42 alone. It is a textbook index by chapter, then topic: quick if you know the chapter, slow if you know only the topic. An update that changes no indexed column can often skip the indexes; with status in any index, every pending-to-confirmed change touched every index.

sql
CREATE INDEX bookings_user_id_idx ON bookings (user_id);
CREATE INDEX bookings_match_status_idx ON bookings (match_id, status);
CREATE UNIQUE INDEX bookings_code_idx ON bookings (booking_code);

EXPLAIN SELECT * FROM bookings WHERE user_id = 812;
-- good: Index Scan using bookings_user_id_idx on bookings
--   or: Bitmap Heap Scan on bookings (over a Bitmap Index Scan)
-- bad:  Seq Scan on bookings

What just happened? The first index serves “My bookings”. The second replaces Arjun’s match_id index and counts sold seats per match, match_id first because every such query names the match. The third finds BK-10421 by its code, and UNIQUE refuses a second booking with the same code.

EXPLAIN shows the plan without running the query; on a tiny table a Seq Scan can be right. A plain CREATE INDEX blocks inserts and updates until done. On a live table, CREATE INDEX CONCURRENTLY avoids that, but builds slower and can leave an invalid index behind if it fails.

Try it yourself

  1. Write three queries

    (a) “My bookings” for one user; (b) sold bookings counted for match 42; (c) booking BK-10421 by its code.

  2. Choose the indexes

    Name each query’s WHERE columns; pick the index and its column order.

  3. Count the writes

    Count where one new booking is written: table, primary key index and yours.

  4. Check your answer

    (a) user_id. (b) (match_id, status), match first. (c) booking_code, ideally UNIQUE. Places: 1 + 1 + 3 = 5. You are right if each index matches a query and none is there as a precaution.

Back to Meera’s phone. The match page asks by id, the primary key, and the database indexes that by itself. “My bookings” asked by user_id, which had none, so the database read the whole book for one word.

Six more made each booking write to 9 places, and four of them helped no screen. Arjun keeps three, so each booking now writes to 5 places, and Meera has her fast demo.

Then Meera has news. The team moves to a new office in Baner, and a senior engineer joins there on Monday. Her first question: should payments, match details and venues all live in the same kind of database?

Check yourself

Check yourself

“My bookings” scans all 10 lakh rows to find user 812’s bookings. What does an index on user_id change?

Pick an answer to see why it is right or wrong.

Check yourself

Arjun indexes every column of the bookings table. What happens at the noon sale?

Pick an answer to see why it is right or wrong.

Check yourself

You have an index on (match_id, status). Which query can jump straight to its rows with one search of the index?

Pick an answer to see why it is right or wrong.

Remember these three

  1. An index is the back-of-the-book index: fast reads, paid for on every write.
  2. A B-tree finds a row in a few page reads, even among crores; a full table scan reads every page.
  3. Index the columns your real queries search, check with EXPLAIN, and drop indexes no query uses.

Questions people ask

What is indexing in DBMS?
Indexing builds a sorted helper structure, an index, so the database finds rows by a column’s value without reading the whole table. Reads get much faster; every write does a little more work.
How does a B-tree index work?
A B-tree keeps sorted values in a tree of pages. The database goes from the root through one branch to one leaf, so a few page reads find the rows, even among crores.
When should you not use an index?
Skip it on small tables, on columns you rarely search, and on tables written far more than read. Each index adds work to every write and takes disk space.