Answer A: Anthropic Claude Fable 5
Understanding Database Indexes: A Practical Guide
What an index is
A database index is a separate data structure the database maintains alongside a table. It stores the values of one or more columns in a sorted, searchable form, together with pointers back to the actual rows. The table itself stores your data; the index is an extra structure whose only job is to help the database find rows faster.
Here is one analogy, and it is the only one you need: an index is like the index at the back of a textbook. If you want every page that mentions "transactions," you do not read the whole book page by page; you look u...
Show Full Answer ▼
Understanding Database Indexes: A Practical Guide
What an index is
A database index is a separate data structure the database maintains alongside a table. It stores the values of one or more columns in a sorted, searchable form, together with pointers back to the actual rows. The table itself stores your data; the index is an extra structure whose only job is to help the database find rows faster.
Here is one analogy, and it is the only one you need: an index is like the index at the back of a textbook. If you want every page that mentions "transactions," you do not read the whole book page by page; you look up "transactions" in the alphabetically sorted index, get a short list of page numbers, and jump straight to them. Without that index, your only option is to scan every page. A database faces exactly the same choice: use an index to jump to matching rows, or scan the whole table.
Now the real behavior, without the analogy. When you run a query like SELECT * FROM orders WHERE customer_id = 42, the database has two basic strategies. A full table scan reads every row and checks the condition, which costs time proportional to the size of the table. An index lookup instead searches the sorted index structure for customer_id = 42, finds the matching entries quickly, and follows the stored pointers to fetch just those rows. For a large table where only a few rows match, the index path can be thousands of times cheaper.
How a B-tree index works, at a high level
The most common index type is a B-tree. It is a balanced tree structure where keys are kept in sorted order. The top node divides the key space into ranges, each child node subdivides further, and the bottom level (the leaves) contains the actual indexed values with pointers to the table rows. Because the tree is balanced and each node holds many keys, even a table with hundreds of millions of rows usually needs only three to five node reads to find any specific value.
Because a B-tree keeps values in sorted order, it supports more than exact matches. It efficiently handles range conditions (WHERE created_at >= '2024-01-01'), prefix matches on strings (WHERE email LIKE 'anna%'), and can return rows already sorted, which lets the database skip a separate sort step for matching ORDER BY clauses.
Why indexes cost something
Indexes are not free, and this is the trade-off you must internalize.
Writes get slower. Every INSERT must add an entry to every index on the table. Every DELETE must remove entries. Every UPDATE that changes an indexed column must update the corresponding index entries. A table with six indexes effectively does up to seven writes for every logical row insert. On write-heavy tables, careless indexing measurably hurts throughput.
Storage grows. Each index is a full copy of the indexed column values plus pointers and tree structure. Indexes on large tables can rival or exceed the size of the table itself, which also affects backups and memory caching.
So the guiding principle is: indexes trade write cost and storage for read speed. You add them where reads benefit clearly, not everywhere.
Selectivity: the key concept for deciding value
Selectivity describes how well a condition narrows down rows. A highly selective column has many distinct values relative to the row count. An email or order ID is highly selective: filtering on it returns one or a handful of rows out of millions, and an index shines. A column like status with three values ('pending', 'shipped', 'cancelled') or a boolean is_active flag has low selectivity: filtering may still match 40% of the table.
Why does this matter? If a condition matches a large fraction of the table, jumping back and forth between the index and the table for millions of rows is often slower than just scanning the table sequentially. Query planners know this and will ignore an index when the estimated match fraction is too high. As a rough intuition, if a typical query using the index would return more than a few percent of the rows, the index may not be used at all, and it is pure overhead.
Composite indexes and the leftmost-prefix rule
An index can cover multiple columns, in a specific order. For example:
CREATE INDEX idx_orders_customer_date ON orders (customer_id, created_at);
Think of this as sorting entries first by customer_id, then by created_at within each customer, like a phone book sorted by last name, then first name.
The leftmost-prefix idea follows directly from that sort order. This index can efficiently serve:
- WHERE customer_id = 42
- WHERE customer_id = 42 AND created_at >= '2024-01-01'
But it cannot efficiently serve WHERE created_at >= '2024-01-01' alone, because entries for a given date range are scattered across all customers; you cannot use a phone book sorted by last name to find everyone named "Anna." The index is usable only when your conditions constrain a prefix of its column list, starting from the leftmost column. This means (customer_id, created_at) and (created_at, customer_id) are different indexes serving different queries, and column order should follow your most important query patterns. A common rule of thumb: put equality-filtered columns first, then the range or sort column.
When an index does not help
- Low selectivity: filtering WHERE is_active = true on a table where 90% of rows are active. The planner will scan instead.
- Functions or expressions on the column: WHERE LOWER(email) = 'x@y.com' cannot use a plain index on email, because the index stores raw values, not transformed ones. (Some databases support expression indexes, but the plain index will not be used.)
- Leading wildcards: WHERE name LIKE '%son' cannot use a B-tree, because the sorted order helps only when the prefix is known.
- Skipping the leftmost column of a composite index, as described above.
- Tiny tables: for a few hundred rows, a scan is already fast; the index adds write cost for no benefit.
- Type mismatches or implicit casts on the indexed column can also prevent index use.
Two small examples
A useful index. Suppose your application constantly runs:
SELECT id, total, created_at
FROM orders
WHERE customer_id = 42
ORDER BY created_at DESC
LIMIT 20;
Then this index fits perfectly:
CREATE INDEX idx_orders_customer_date ON orders (customer_id, created_at);
The database jumps to customer 42's entries, which are already sorted by created_at, reads the newest 20, and stops. It is fast on a table of any size, and it also serves plain lookups by customer_id thanks to the leftmost prefix.
A problematic index. Suppose you instead create:
CREATE INDEX idx_orders_status ON orders (status);
where status has three possible values and most rows are 'shipped'. A query like SELECT * FROM orders WHERE status = 'shipped' matches most of the table, so the planner will do a table scan anyway. The index is rarely or never used, yet every insert and every status update pays to maintain it. This is a net loss. (An exception worth knowing: indexing a low-cardinality column can pay off when one value is rare and heavily queried, such as the small set of 'pending' orders, but the generic version above is a classic mistake.)
Practical checklist before adding an index
- Identify the actual slow query first; do not index speculatively. Look at real query patterns and use EXPLAIN to see the current plan.
- Check selectivity: will typical queries using this index return a small fraction of the table? If not, reconsider.
- For multi-column filters and sorts, design one composite index with the right column order (equality columns first, then range/sort columns) rather than several single-column indexes.
- Confirm the leftmost-prefix rule: does your most common query constrain the first column of the index?
- Make sure the query does not defeat the index with functions, leading wildcards, or type casts on the indexed column.
- Weigh write traffic: on heavily written tables, every extra index has a real cost. Remove indexes that overlap with or are prefixes of others.
- Check whether an existing index already covers the query before creating a new one.
- After creating the index, verify with EXPLAIN that the planner actually uses it, and measure the query time before and after.
- Periodically review and drop unused indexes; they cost writes and storage forever.
The core mental model to keep: an index is a sorted lookup structure you pay for on every write so that specific, selective reads become cheap. Add one when you can name the query it serves and show that it helps.
Result
Winning Votes
3 / 3
Average Score
Total Score
Overall Comments
Answer A is thorough, accurate, and exceptionally well-matched to the target audience. It cleanly separates the analogy from the real database behavior (as the prompt explicitly requested), explains B-tree structure with concrete detail about node reads, and covers write costs, storage, and selectivity with correct nuance including the case where indexing a rare low-cardinality value can still pay off. It fully addresses composite indexes and the leftmost-prefix rule with a strong phone-book illustration, and includes a rich "when an index does not help" section (functions, leading wildcards, type casts, tiny tables). The two SQL examples are coherent and directly tied to query patterns, and the checklist is highly actionable, referencing EXPLAIN, measurement, and dropping unused indexes. Minor weakness: it is longer and denser than strictly necessary, but this rarely harms comprehension given the strong structure.
View Score Details ▼
Clarity
Weight 30%Explanations are precise and build logically; the deliberate separation of analogy from real behavior, the phone-book illustration for column order, and the closing mental model make abstract concepts vivid. Slightly denser than B but never confusing.
Correctness
Weight 25%Technically accurate throughout, including subtle points: planners ignoring low-selectivity indexes, expression indexes as an exception, leading-wildcard failure, type-cast issues, and the correct note that a rare heavily-queried low-cardinality value can still benefit. B-tree node-read estimate is reasonable.
Audience Fit
Weight 20%Well-tuned to a junior developer who knows SELECT/WHERE/JOIN: it avoids deep internals, names the practical rules of thumb, and ties every concept to a decision the developer can make. Density is the only minor risk for a novice.
Completeness
Weight 15%Covers every requested element and more: index-as-structure, read speedup, write/storage cost, high-level B-tree, selectivity, composite indexes, leftmost prefix, multiple non-helping cases, two contrasting SQL examples, and a rich checklist including EXPLAIN and dropping unused indexes.
Structure
Weight 10%Logical, well-sectioned flow from definition through tradeoffs, selectivity, composite indexes, non-helping cases, examples, and checklist. Slightly heavier text blocks reduce scannability compared with B.
Total Score
Overall Comments
Answer A provides an exceptionally clear, comprehensive, and practical explanation of database indexes tailored perfectly for a junior backend developer. It covers all required topics with excellent depth, including a robust section on situations where indexes don't help and a highly actionable checklist. The analogies and direct explanations are well-integrated, and the SQL examples are pertinent.
View Score Details ▼
Clarity
Weight 30%Answer A is exceptionally clear, using well-structured headings, precise language, and effective analogies (like the phone book for leftmost-prefix) to explain complex concepts. The flow is logical and easy to follow.
Correctness
Weight 25%Answer A is highly accurate across all explanations, from the B-tree mechanics to the nuances of selectivity and composite indexes. It correctly identifies various scenarios where indexes are beneficial or detrimental, including supporting range queries and ORDER BY clauses with B-trees.
Audience Fit
Weight 20%Answer A is perfectly tailored for a junior backend developer. The language is accessible, the analogy is simple and effective, and the practical advice is comprehensive without being overwhelming. The 'core mental model' at the end is a great summary for the target audience.
Completeness
Weight 15%Answer A is highly complete, covering all requested topics in depth. It provides a very comprehensive list of situations where an index may not help and a detailed, actionable checklist, exceeding expectations for practical guidance.
Structure
Weight 10%Answer A has an excellent structure with clear, descriptive headings that guide the reader through the material logically. Each concept is introduced and explained in a well-organized manner, making the content easy to digest.
Total Score
Overall Comments
Answer A is a highly complete, accurate, and well-structured teaching explanation. It clearly explains indexes as separate sorted lookup structures, covers B-tree behavior, read/write/storage tradeoffs, selectivity, composite indexes, leftmost-prefix behavior, and many situations where indexes may not help. Its examples are practical and its final checklist is directly actionable. Minor weaknesses are a few broad simplifications, such as implying certain B-tree LIKE-prefix behavior generically and saying the example index is fast on a table of any size, but these do not materially harm the explanation.
View Score Details ▼
Clarity
Weight 30%Answer A is very clear, with direct explanations, concrete examples, and smooth transitions from analogy to real database behavior. It is somewhat long, but the detail generally improves understanding rather than obscuring it.
Correctness
Weight 25%Answer A is technically accurate for a generic relational database at the intended level. It correctly explains separate index structures, B-tree lookup, read/write/storage tradeoffs, selectivity, composite index ordering, and common non-use cases, with only minor generic simplifications.
Audience Fit
Weight 20%Answer A is well matched to a junior backend developer who knows basic SQL. It gives practical mental models, realistic examples, and actionable guidance, though its breadth may be slightly dense for a first introduction.
Completeness
Weight 15%Answer A covers nearly every requested element: what indexes are, read speedups, write and storage costs, B-tree behavior, selectivity, composite indexes, leftmost-prefix behavior, multiple cases where indexes may not help, two SQL examples, and a strong checklist.
Structure
Weight 10%Answer A is very well organized, with clear headings, logical progression, examples placed after concepts, and a practical checklist at the end. The structure strongly supports learning.