Aikido

Why avoid redundant database indexes: optimizing storage and write performance

Performance

Rule

Avoid redundant database indexes.
Overlapping database indexes waste
storage and slow down writes.

Supported languages: SQL

Introduction

Redundant indexes occur when multiple indexes cover the same columns or when one index is a prefix of another. Every index consumes disk space and must be updated on INSERT, UPDATE, and DELETE operations. A table with five overlapping indexes on similar columns pays the write performance penalty five times while only one index would suffice for read optimization.

Why it matters

Performance impact: Every index slows down write operations because the database must update all indexes when data changes. Redundant indexes multiply this cost without providing query benefits. A table with three redundant indexes on user_id triples write overhead while only one index is ever used.

Storage costs: Indexes consume disk space proportional to indexed column sizes and row counts. Redundant indexes waste storage that could be used for actual data or useful indexes. Large tables with unnecessary indexes can waste gigabytes of storage.

Maintenance complexity: More indexes mean more objects to monitor, analyze, and maintain. Database administrators spend time optimizing indexes that provide no value. Query planners have more options to evaluate, potentially choosing suboptimal execution plans.

Code examples

❌ Non-compliant:

-- Redundant indexes on users table
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_email_status ON users(email, status);
CREATE INDEX idx_users_created ON users(created_at);
CREATE INDEX idx_users_created_status ON users(created_at, status);

-- The single-column indexes are redundant because
-- the composite indexes can serve the same queries

Why it's wrong: The index on email is redundant because idx_users_email_status starts with email and can handle queries filtering only by email. Similarly, idx_users_created is redundant with idx_users_created_status. Every insert or update to this table updates four indexes when two would suffice.

✅ Compliant:

-- Optimized indexes on users table
CREATE INDEX idx_users_email_status ON users(email, status);
CREATE INDEX idx_users_created_status ON users(created_at, status);

-- Composite indexes can serve queries on their prefix columns
-- Queries on just email use idx_users_email_status
-- Queries on just created_at use idx_users_created_status

Why this matters: Two composite indexes serve all query patterns while eliminating redundancy. Queries filtering by email alone use the first index, and queries filtering by created_at alone use the second. Write performance improves because only two indexes need updates instead of four.

Conclusion

Audit your database indexes regularly to identify redundant ones. Remove indexes that are prefixes of other indexes or that duplicate coverage. Composite indexes can serve queries on their leading columns, eliminating the need for separate single-column indexes in most cases.

FAQs

Got Questions?

How do I identify redundant indexes in my database?

Query your database's system tables to list all indexes. For PostgreSQL, use pg_indexes view. For MySQL, use SHOW INDEX FROM table_name. Look for indexes where one is a prefix of another (email vs email+status) or where multiple indexes cover the same columns in different orders.

When is a single-column index not redundant with a composite index?

When query selectivity matters. If you frequently query only the second column of a composite index, that query can't use the index efficiently. An index on (status, email) won't help queries filtering only by email. However, an index on (email, status) can serve queries on just email.

How do redundant indexes affect query performance?

Minimally for reads, significantly for writes. The query planner might choose between redundant indexes, but execution time is similar. However, every write (INSERT, UPDATE, DELETE) must update all indexes, multiplying I/O operations. For write-heavy tables, removing redundant indexes can improve throughput by 20-50%.

Should I remove all single-column indexes if I have composite indexes?

Not always. If the single-column index is highly selective and frequently queried alone, keep it. Use database query statistics to see which indexes are actually used. Drop indexes with zero or very low usage. Modern databases track index usage in system views.

Get secure for free

Secure your code, cloud, and runtime in one central system.
Find and fix vulnerabilities fast automatically.

No credit card required | Scan results in 32secs.