SQL Indexes
The Search Problem: Finding Information Quickly
Database Query Performance
Today's Learning Objectives
What is a Database Index?
Index Analogies
Querying Without an Index: Full Table Scan
SELECT user_id, email
FROM users
WHERE registration_date = '2023-10-26';
The Inefficiency of Full Table Scans
Querying With an Index: Index Scan / Lookup
SELECT user_id, email
FROM users
WHERE registration_date = '2023-10-26';
Why Use Indexes? Key Benefits
How Indexes Work: The Core Idea
The B-Tree Index: PostgreSQL's Default
B-Tree Structure
Searching a B-Tree
B-Tree Strengths
Beyond B-Trees: Index Types in PostgreSQL
Index Type: B-Tree
Index Type: Hash
Index Type: GIN �(Generalized Inverted Index)
Index Type: GiST (Generalized Search Tree)
Index Type: BRIN (Block Range Index)
Other Indexing Concepts (1/4): �Multi-Column Indexes
Other Indexing Concepts (2/4): �Unique Indexes
CREATE UNIQUE INDEX idx_users_email ON users (email);
-- Or often implicitly via constraints:
ALTER TABLE users ADD CONSTRAINT users_email_unique UNIQUE (email); -- Uses a unique index behind the scenes
Other Indexing Concepts (3/4): Partial Indexes
CREATE INDEX idx_orders_pending
ON orders (order_id)
WHERE status = 'pending';
Other Indexing Concepts (4/4): Expression Indexes
-- Index case-insensitive email lookups
CREATE INDEX idx_users_email_lower
ON users (lower(email));
-- This query CAN use the index:
SELECT * FROM users WHERE lower(email) = 'test@example.com';
Index Management: Creating Indexes
CREATE INDEX [index_name]
ON table_name [ USING method ] ( column1 [, column2, ...] )
[ WHERE predicate ]; -- For Partial Indexes
Creating Indexes: Examples
CREATE INDEX idx_users_email ON users (email);
-- Equivalent to: CREATE INDEX idx_users_email ON users USING btree (email);
-- Assuming 'tags' is an array type column (e.g., TEXT[])
CREATE INDEX idx_posts_tags ON posts USING GIN (tags);
CREATE INDEX idx_orders_pending ON orders (order_id)
WHERE status = 'pending';
Index Management: Dropping Indexes
DROP INDEX [IF EXISTS] index_name;
DROP INDEX idx_users_email;
Index Management: Viewing Existing Indexes
\d users
SELECT indexname, indexdef
FROM pg_indexes
WHERE tablename = 'users';
Index Usage: The Query Planner
Verifying Index Usage: �The EXPLAIN Command
EXPLAIN [ANALYZE] SELECT columns
FROM table_name
WHERE condition;
EXPLAIN Output: Seq Scan vs. Index Scan
EXPLAIN SELECT * FROM users WHERE registration_date = '2023-10-26’;
QUERY PLAN
-------------------------------------------------------------
Seq Scan on users (cost=0.00..5000.00 rows=10 width=120)
Filter: (registration_date = '2023-10-26'::date)
(Seq Scan = Sequential Scan = Full Table Scan)
EXPLAIN Output: Seq Scan vs. Index Scan
QUERY PLAN
--------------------------------------------------------------------------
Index Scan using idx_users_reg_date on users (cost=0.40..8.42 rows=10 width=120)
Index Cond: (registration_date = '2023-10-26'::date)
-- OR sometimes:
Bitmap Heap Scan on users (cost=4.50..100.50 rows=10 width=120)
Recheck Cond: (registration_date = '2023-10-26'::date)
-> Bitmap Index Scan on idx_users_reg_date (cost=0.00..4.49 rows=10 width=0)
Index Cond: (registration_date = '2023-10-26'::date)
The Costs of Indexing: No Free Lunch
Trade-off 1: Write Performance Penalty
Trade-off 2: Storage Space
Trade-off 3: Maintenance Overhead
Indexing Strategy: Key Considerations
Lecture Summary: SQL Indexes