Lab 05: Advanced Indexing

Time: 40 minutes | Level: Practitioner | DB: PostgreSQL 15 + MySQL 8.0

Indexes are the single biggest lever for query performance. This lab covers composite, partial, covering, GIN, and GiST indexes — and when each is the right tool.


Step 1 — Setup: Products Table with 10,000 Rows

-- PostgreSQL
CREATE TABLE products (
  id        SERIAL PRIMARY KEY,
  name      VARCHAR(100),
  category  VARCHAR(50),
  price     NUMERIC(10,2),
  stock     INT,
  tags      TEXT[],
  metadata  JSONB,
  is_active BOOLEAN DEFAULT true
);

INSERT INTO products (name, category, price, stock, tags, metadata, is_active)
SELECT
  'Product ' || i,
  CASE (i % 5)
    WHEN 0 THEN 'Electronics' WHEN 1 THEN 'Clothing'
    WHEN 2 THEN 'Books'       WHEN 3 THEN 'Food'
    ELSE 'Sports' END,
  (RANDOM() * 500 + 1)::NUMERIC(10,2),
  (RANDOM() * 1000)::INT,
  ARRAY['tag' || (i%10), 'cat' || (i%5)],
  jsonb_build_object('brand', 'Brand'||(i%20), 'rating', (RANDOM()*5)::NUMERIC(3,1)),
  (i % 10 != 0)
FROM generate_series(1, 10000) i;

ANALYZE products;

📸 Verified Output:


Step 2 — Composite Indexes: Column Order Matters

💡 Left-prefix rule: A composite index (A, B, C) can be used for queries filtering on A, A+B, or A+B+C — but NOT B alone, C alone, or B+C alone.

📸 Verified Output:


Step 3 — Partial Indexes (PostgreSQL)

📸 Verified Output:

💡 Partial indexes are smaller (fewer pages), cheaper to update, and have better cache utilization. If 10% of products are inactive, your index is 10% the size.


Step 4 — Covering Indexes (Index-Only Scans)

💡 A covering index returns results without reading the heap table at all — look for Index Only Scan in PostgreSQL EXPLAIN or Using index in MySQL EXPLAIN.


Step 5 — GIN Index: Arrays and JSONB

📸 Verified Output (index list):


Step 6 — GiST Index and Full-Text GIN

💡 GIN vs GiST: GIN is faster for reads (containment, equality); GiST is faster for writes and supports range/geometric types. Choose GIN for JSONB/arrays/FTS, GiST for ranges and PostGIS.


Step 7 — MySQL Prefix Indexes and Index Bloat

PostgreSQL: Index bloat and REINDEX


Step 8 — Capstone: Index Strategy for an E-commerce Query

Design indexes for this complex query and verify the plan:


Summary

Index Type
Operator
Best For

B-tree (default)

=, <, >, BETWEEN, LIKE 'abc%'

Most queries

Composite B-tree

Multiple column equality/range

Multi-column WHERE

Partial

Any + WHERE clause

Frequently filtered subset

Covering

Exact column list

Index-only scans

GIN

@>, &&, ?, @@

Arrays, JSONB, full-text

GiST

&&, <->, overlap

Ranges, geometry, FTS

Prefix (MySQL)

=, LIKE 'x%'

Long VARCHAR columns

Last updated