🗄️SQL Templates

Index Creation & Optimization

Create indexes to improve query performance and understand index types

Explanation

Indexes speed up data retrieval but slow down writes. Learn when and how to use them effectively.

Examples

Simple index
Input
CREATE INDEX idx_email ON users(email)
Output
Speeds up email lookups
Composite index
Input
CREATE INDEX idx_user_date ON orders(user_id, created_at)
Output
Optimizes multi-column queries

Code Examples

SQL
-- Create simple index
CREATE INDEX idx_email ON users(email);

-- Create unique index
CREATE UNIQUE INDEX idx_username ON users(username);

-- Composite index (multiple columns)
CREATE INDEX idx_user_status 
ON orders(user_id, status);

-- Composite index with order
CREATE INDEX idx_user_date 
ON orders(user_id, created_at DESC);

-- Partial index (PostgreSQL)
CREATE INDEX idx_active_users 
ON users(email) 
WHERE status = 'active';

-- Expression index
CREATE INDEX idx_lower_email 
ON users(LOWER(email));

-- Full-text index (MySQL)
CREATE FULLTEXT INDEX idx_product_search 
ON products(name, description);

-- Spatial index (for geographic data)
CREATE SPATIAL INDEX idx_location 
ON stores(coordinates);

-- Drop index
DROP INDEX idx_email ON users;

-- View indexes
SHOW INDEXES FROM users;

-- Analyze index usage (PostgreSQL)
SELECT 
  schemaname,
  tablename,
  indexname,
  idx_scan,
  idx_tup_read,
  idx_tup_fetch
FROM pg_stat_user_indexes
ORDER BY idx_scan DESC;

-- Check index size
SELECT 
  indexname,
  pg_size_pretty(pg_relation_size(indexrelid)) AS size
FROM pg_stat_user_indexes
WHERE schemaname = 'public';

-- Explain query plan
EXPLAIN ANALYZE
SELECT * FROM users WHERE email = 'test@example.com';

-- Force index usage (MySQL)
SELECT * FROM users 
USE INDEX (idx_email)
WHERE email = 'test@example.com';

-- Index recommendations
-- Index columns used in:
-- - WHERE clauses
-- - JOIN conditions
-- - ORDER BY clauses
-- - Foreign keys

-- Example: Optimize this query
-- Before:
SELECT * FROM orders 
WHERE user_id = 123 
  AND status = 'pending'
ORDER BY created_at DESC;

-- Create index:
CREATE INDEX idx_user_status_date 
ON orders(user_id, status, created_at DESC);

💡 Tips

  • Index columns used in WHERE, JOIN, ORDER BY
  • Leftmost prefix of composite index can be used alone
  • Unique indexes enforce uniqueness and improve speed
  • Too many indexes slow down INSERT/UPDATE/DELETE
  • Use EXPLAIN to verify index usage
  • Index selectivity matters (unique > low cardinality)
  • Foreign keys should be indexed
  • Monitor index usage and drop unused ones

⚠️ Common Pitfalls

  • Over-indexing slows writes and wastes space
  • Function calls in WHERE prevent index usage
  • Leading wildcards (LIKE '%text') can't use index
  • OR conditions may not use index efficiently
  • Column order matters in composite indexes
  • Indexes need maintenance (REINDEX, OPTIMIZE)
  • Small tables may not benefit from indexes