4.4.13 · D5Databases

Question bank — Indexing — B-tree index, hash index, full-text

1,383 words6 min readBack to topic

True or false — justify

An index makes every query on a table faster.
False — an index only helps queries that filter/join/sort on the indexed column(s); an unrelated WHERE other_col = ? still does a full scan, and meanwhile every write got slower.
A B-tree index stores an exact copy of the whole row.
False — it stores the indexed column value(s) plus a row pointer (or the primary key). The full row lives in the heap or clustered file; a non-clustered index just points to it.
Because , a hash index is strictly better than a B-tree.
False — see Big-O Notation: is ~5 for a billion rows, a tiny constant, while a hash index cannot do ranges, ORDER BY, or prefix LIKE. B-tree wins for most real workloads.
A B+tree's internal nodes hold the actual row pointers.
False — in a B+tree only the leaves hold key→pointer pairs; internal nodes hold only separator keys that route the search downward.
Adding one more index has zero downside if the table is read-only.
True-ish — on a truly read-only table the write cost vanishes, so only the storage cost remains. On any table that gets writes, though, every INSERT/UPDATE/DELETE must maintain that index.
A hash index keeps its keys in sorted order inside each bucket.
False — hashing deliberately scatters keys across buckets to spread them evenly; there is no global order to exploit for ranges or sorting.
ORDER BY indexed_col is free with a B-tree index.
True — B+tree leaves are stored and linked in sorted order, so the database can walk them sequentially instead of running a separate sort step.
A full-text index and a B-tree index on the same text column do the same job.
False — a B-tree helps col = 'x' or LIKE 'pre%', but searching inside text (CONTAINS 'x') needs an inverted index mapping word→documents; a B-tree cannot do word-inside-text search.

Spot the error

"I added an index on (last_name, first_name), so my query filtering only on first_name is now fast."
Wrong — the leftmost-prefix rule: a composite index is sorted by last_name first, so it can't jump to a first_name without knowing the last_name. It helps last_name or both, never first_name alone.
"My column has an index, so WHERE name LIKE '%son' uses it."
Wrong — a leading wildcard gives no known prefix to start the descent, so the B-tree can't pick a starting leaf → full scan. Only LIKE 'son%' (trailing wildcard) can use the index.
"Hash indexes are perfect for my WHERE price BETWEEN 10 AND 20 query."
Wrong — hashing destroys order, so adjacent prices land in unrelated buckets. Range queries fall back to a full scan on a hash index; use a B-tree.
"The database is slow, so I'll index every column to be safe."
Wrong — each index costs storage and must be updated on every write. On write-heavy tables, over-indexing makes the system slower. Index only columns you actually filter/join/sort on.
"My table has a billion rows so a lookup needs a billion comparisons."
Wrong — with a B-tree of branching factor ~100, height , so ~5 disk reads (often 1–2 with top levels cached in RAM). See B+ Tree Data Structure.
"Full-text search stores documents mapping doc→its words, and searches that."
Wrong — that's a forward index. Full-text uses an inverted index (word→documents) because the query gives you a word and asks which documents contain it.
"Indexes speed up reads by reducing CPU work."
Mostly wrong — the real bottleneck is disk I/O. Indexes turn page reads into or ; saving seeks matters far more than saving CPU comparisons.

Why questions

Why are B-tree nodes made as wide as one disk page (~8 KB)?
Because reading one node = one disk seek, and seeks are the expensive part. A wide node means high branching factor , which makes the tree shallow (), so fewer levels = fewer seeks.
Why does the index deliberately duplicate data instead of reusing the table?
The table is stored by insertion/clustering order, not by the searched column. A separate sorted or hashed copy is what lets the database jump straight to matches without scanning.
Why is it called an inverted index?
A natural index maps document→words. We invert it to word→documents because the query hands us the word and wants the documents — matching the query's direction makes lookup a direct jump instead of a scan.
Why do full-text engines apply stemming and stop-word removal before indexing?
Stemming collapses running/ran/runsrun so one lookup matches all forms; stop-word removal drops the/is which appear everywhere and carry no search value, shrinking postings lists.
Why can B-trees answer range queries but hash indexes cannot?
B+tree leaves are kept sorted and linked, so you find the start then walk the neighbours. Hashing scatters keys with no relationship between hash(99) and hash(100), so there's no neighbour to walk.
Why does a lookup cost roughly the height of the B-tree in disk reads?
Each level down the tree is one node, and each node is one disk page = one read. You touch one node per level from root to leaf, so cost ≈ height ≈ .

Edge cases

What does a B-tree lookup cost when the whole tree fits in RAM?
Still comparisons, but ~0 disk seeks — the "disk read per level" cost collapses because pages are cached. The algorithm's shape is unchanged; only the I/O cost drops.
What happens to a hash index when many keys collide into one bucket?
That bucket degrades toward a list, so lookups in it drift from toward . Good hash functions and enough buckets keep collisions rare; a bad one erases the advantage.
Does an index on a boolean or very low-cardinality column help?
Rarely — if a column has only 2–3 distinct values, each value still matches a huge fraction of rows, so the database often prefers a full scan anyway. Low selectivity defeats the index.
Can a query on an empty or single-row table benefit from an index?
No meaningful benefit — scanning 0 or 1 rows is already trivial. The index only pays off once is large enough that or beats reading everything.
What happens if you index a column and then query it with a function, e.g. WHERE LOWER(email) = 'x'?
The plain index on email can't be used — the index stores raw values, not LOWER(...) of them. You need a functional/expression index on LOWER(email) to match.
How does LIKE 'app%' behave versus LIKE '%app%' on a B-tree index?
'app%' has a known prefix, so the tree descends to app and walks the range — index-usable. '%app%' has no starting prefix, so it degenerates to a full scan; use a full-text index instead.
What's the cost of a range query returning matching rows on a B-tree?
: to find the first match, then steps walking the linked leaves. Returning many rows is dominated by , not by the tree descent.

Recall One-line self-test

Cover the reasons above and re-answer each. If your reason was "yes/no" with no why, you haven't learned the trap — the exam always asks the why.