MySQL Tuning, Indexing & Concurrency
8-10 Years (Tech Lead)
Hard
Production Scenario
How does the InnoDB B+Tree Index work internally, and why does Leftmost Prefix Rule dictate composite index column ordering?
Real-World Scenario / Incident Description
A query `WHERE status = "active" AND created_at >= "2026-01-01" AND user_id = 500` was doing a full table scan across 30 million rows despite having an index on `(created_at, status, user_id)`.
134 views
•
Updated 3 weeks ago
Why B+Tree Needs Leftmost Prefix Rule
In an InnoDB B+Tree, index keys are sorted lexicographically based on the order of columns defined in the index: (ColA, ColB, ColC).
- If a query filters on
ColBwithoutColA, the B+Tree root cannot branch becauseColBis only sorted within duplicate values ofColA. - Range Queries Stop Index Filtering: Once a range operator (
>,<,BETWEEN,>=) is evaluated, subsequent columns in the composite index cannot be used for B+Tree traversal.
Fixing the Slow Query
Because created_at used a range operator (>=), placing it first broke index lookups for status and user_id.
Optimal Composite Index Column Order:
- Exact equality matches with highest cardinality first:
user_id - Equality match:
status - Range match last:
created_at
ALTER TABLE orders ADD INDEX idx_user_status_created (user_id, status, created_at);
Query execution time drops from 8.5 seconds (full scan) to 0.8 milliseconds (index seek).
Related Concepts:
#MySQL
#InnoDB
#B+Tree
#Composite Index
#Leftmost Prefix
More MySQL Tuning, Indexing & Concurrency Interview Questions
Explain InnoDB Locking Modes: Record Locks, Gap Locks, and Next-Key Locks, and how they prevent Phantom Reads.
Read →
How do you optimize deep pagination (`SELECT * ... LIMIT 5000000, 20`) on large tables with 100M rows?
Read →
How do you interpret MySQL `EXPLAIN ANALYZE` output to diagnose `Using filesort` and `Using temporary`?
Read →
Explain MySQL Table Partitioning (Range, List, Hash) vs. Application-Level Sharding for 1TB+ databases.
Read →
How does the InnoDB Buffer Pool manage dirty pages, and how do you size `innodb_buffer_pool_size` for production servers?
Read →