CREATE INDEX builds an auxiliary data structure that accelerates SELECT queries by letting PostgreSQL locate rows without scanning the entire table.
Slow query performance often comes from full-table scans. CREATE INDEX adds a separate, ordered data map so PostgreSQL can jump straight to the rows you need, cutting I/O and latency dramatically.
Add indexes to columns frequently used in WHERE, JOIN, ORDER BY, or DISTINCT clauses. Typical picks are Orders.customer_id, OrderItems.order_id, and Products.name for keyword search.
B-tree (default) fits exact matches and range queries. Hash works for equality only. GIN/GiST handle JSONB or full-text search, while BRIN helps on large, naturally ordered tables like Orders(order_date).
Use CREATE INDEX, optionally add CONCURRENTLY to avoid table locks, pick a descriptive name, and list columns in the most selective order.
Yes. Add a WHERE clause to index only rows that matter, e.g., recent orders, reducing size while boosting performance where it counts.
Run EXPLAIN (ANALYZE, BUFFERS) before and after indexing. Look for Index Scan or Index Only Scan nodes and lower total cost in the plan.
Name indexes consistently: table_column_idx. Avoid redundant indexes—PostgreSQL can use a multi-column index for the leading column alone. Reindex or drop unused indexes to save storage.
No, it builds a separate structure. With CONCURRENTLY, reads and writes continue during the build.
Yes. PostgreSQL can use the leading column, but not the trailing ones alone.
Use DROP INDEX [CONCURRENTLY] index_name; verify no query plans rely on it first.