I would start by analyzing the queries to determine which columns are used most frequently in WHERE clauses and JOIN conditions. Based on this analysis, I would create appropriate indexes on these columns, particularly covering indexes if multiple columns are involved, to speed up range queries while being mindful of write performance and maintenance costs associated with these indexes.
In depth
Indexing is crucial for optimizing query performance, especially for large tables where full table scans can be prohibitively slow. For queries that involve specific ranges, I would focus on creating B-tree indexes on the relevant columns as they perform well for range queries. Additionally, I would consider composite indexes if queries filter on multiple columns. However, it's important to remember that while indexes can accelerate read operations, they can also slow down write operations due to the overhead of maintaining the index, so I would strike a balance based on the read-to-write ratio of the application. Lastly, I would monitor the performance regularly and be prepared to adjust the indexing strategy based on changing query patterns or data distribution over time.
Example scenario
At my previous job with an e-commerce platform, we had a large 'orders' table that was often queried for data within specific order dates. We noticed that performance was degrading as the table grew. After analyzing query patterns, we implemented a composite index on the 'order_date' and 'customer_id' columns. This change significantly improved the speed of our reports and queries that filtered on these columns, reducing response times from several seconds to milliseconds. We also monitored the impacts on write operations and adjusted our indexing strategy based on user behavior and usage patterns.
Common mistakes
One common mistake is over-indexing, which can lead to unnecessary performance hits during write operations, increasing maintenance time and storage costs. Developers may also create indexes without analyzing query patterns, leading to indexes that are seldom used and providing little benefit. Another error is failing to consider the impact of data distribution; for example, indexing a column with low cardinality might not improve query performance, as the database engine still has to scan multiple rows to fulfill the query.
Follow-up questions
- What tools or methods do you use to analyze query performance?
- How do you decide when to drop an index?
- Can you explain the concept of covering indexes and when to use them?
- What are the trade-offs between B-tree and hash indexes?

Preparing for a system design interview?
- A 7-step method for answering any system design question, plus estimation numbers
- 5 worked designs: URL shortener, rate limiter, chat, news feed and file storage
- Guides to caching, databases, queues, consistency and reliability, with a 4-week study plan
- 306 practice questions with answers on caching, databases, queues, microservices, APIs and more
5 worked designs, a 4-week plan and 306 practice questions with answers.
The material stays free to read online. This is the organised, offline, print-ready PDF edition. Secure payment by PayPal; your personal download link is emailed after payment is confirmed. Digital product, no shipping.