How to create and use indexes in SQL
Speed up queries by creating indexes on frequently queried columns.
CREATE INDEX idx_users_email ON users(email);Speeds up queries that filter or sort by email. Name your indexes descriptively.
When to use: Columns frequently used in WHERE, JOIN ON, or ORDER BY.
CREATE UNIQUE INDEX idx_users_email_unique ON users(email);Enforces uniqueness and speeds up lookups. Equivalent to a UNIQUE constraint.
CREATE INDEX idx_orders_user_status ON orders(user_id, status);Indexes multiple columns together. Speeds up queries that filter by both columns.
When to use: Queries that filter by multiple columns together.
Column order matters β this index helps WHERE user_id = ? AND status = ? but not WHERE status = ? alone.
CREATE INDEX CONCURRENTLY idx_orders_user_id ON orders(user_id);Builds the index without locking the table. Slower but safe for production.
When to use: Adding indexes on large production tables without downtime.
SELECT
indexname,
tablename,
indexdef
FROM pg_indexes
WHERE schemaname = 'public'
ORDER BY tablename;Shows all indexes in the public schema.
DROP INDEX idx_users_email;
-- PostgreSQL: won't lock the table:
DROP INDEX CONCURRENTLY idx_users_email;Removes an index. Use CONCURRENTLY in PostgreSQL to avoid table lock.
Common Mistakes
- βOver-indexing β every index slows down INSERT/UPDATE/DELETE. Only index what you query.
- βIndexing low-cardinality columns (boolean, status with 3 values) β often not worth it.
- βNot using CONCURRENTLY in production PostgreSQL β locks the table during index creation.