SQL Practice Logo

SQLPractice Online

Index Design & Selection: Functions

Module: Query Optimization & Performance

**Single-Column Index:**

CREATE INDEX idx_email ON users(email);

-- For: WHERE email = 'user@example.com'

-- Simple, works for any query on email

**Composite Index (Column Order Matters):**

CREATE INDEX idx_user_status_date ON orders(

user_id, -- Most selective, equality

status, -- Equality

created_at -- Range (last)

);

-- For: WHERE user_id = 123 AND status = 'pending' AND created_at > '2024-01-01'

-- Can also use for: WHERE user_id = 123 (leftmost prefix)

-- Cannot use for: WHERE status = 'pending' (doesn't start with user_id)

**Covering Index (Includes SELECT Columns):**

CREATE INDEX idx_orders_covering ON orders(

user_id, -- WHERE

status, -- WHERE

created_at, -- WHERE

total, -- SELECT

product_id -- SELECT

);

-- For: SELECT total, product_id WHERE user_id = 123 AND status = 'pending'

-- Index-only scan (no table access)

-- Fastest possible

**Partial Index (Filtered Subset):**

CREATE INDEX idx_active_users ON users(email, created_at)

WHERE active = true; -- Only index active users

-- 80% smaller if only 20% are active

-- Faster to scan

-- Lower write overhead

**Unique Index (Enforces Constraint):**

CREATE UNIQUE INDEX idx_username ON users(username);

-- Prevents duplicate usernames

-- Faster lookups (optimizer knows unique)

**Function-Based Index:**

CREATE INDEX idx_email_lower ON users(LOWER(email));

-- For: WHERE LOWER(email) = 'user@example.com'

-- Enables case-insensitive search

**Monitoring Index Usage (PostgreSQL):**

SELECT