Index Optimization — Boost Query Speed with Smart Indexing

Choose Effective Indexes

Reports often filter by class and then sort marks. Several single-column indexes may not serve that combined access pattern as well as an appropriate composite index.

Index optimization chooses a small, useful set of indexes for actual filters, joins and ordering needs, while accounting for write and storage costs.

  1. Explain and apply

    Match index columns to a query and explain why adding more indexes has a cost.

  2. Work it out

    Create a class/marks index, then run the class report with the same logical result.

  3. Avoid mistakes

    Leftmost-prefix behavior is a useful basic model, with engine-specific exceptions and optimizer features.

Choose Effective Indexes: the request and its result

  1. School need

    Reports often filter by class and then sort marks. Several single-column indexes may not serve that combined access pattern as well as an appropriate composite index.

  2. Database operation

    Index optimization chooses a small, useful set of indexes for actual filters, joins and ordering needs, while accounting for write and storage costs.

  3. Check the outcome

    The index offers a class-first access path. Whether this fixture uses it is an observation from the plan, not a promised outcome of creating it.

A conceptual model. The query examples below show the actual syntax, input data and results.

Understand what the database does

Column order matters in a composite B-tree index. Its leading columns influence which predicates can use an efficient lookup. A covering index can provide needed values without an additional base-row lookup for supported plans. Measure alternatives rather than adding every possible combination.

Related concepts: Indexes and Read Execution Plans.

What is an Index?

An index is a database object that speeds up data retrieval operations. It is built on one or more columns of a table. Indexes allow the database to find rows efficiently without scanning the entire table.

Types of Indexes

  • Primary Index – Automatically created on primary key
  • Unique Index – Prevents duplicates in specific columns
  • Composite Index – Built on two or more columns
  • Covering Index – Index that includes all required columns for a query

Basic Example – students Table

SQL · portable concepts; preserved examples identify their engine

CREATE TABLE students (
  roll_no INT PRIMARY KEY,
  name VARCHAR(50),
  class VARCHAR(10),
  city VARCHAR(30)
);

1. Single-Column Index

SQL · portable concepts; preserved examples identify their engine

-- Without index
EXPLAIN SELECT * FROM students WHERE class = '10A';

-- Add index
CREATE INDEX idx_class ON students(class);

-- Now re-run
EXPLAIN SELECT * FROM students WHERE class = '10A';
Before: type = ALL (full scan)  
After:  type = ref (uses index)

2. Composite Index (Multi-Column)

SQL · portable concepts; preserved examples identify their engine

If you frequently filter by both class and city together:

CREATE INDEX idx_class_city ON students(class, city);

Important: The order matters. This index helps:

SELECT * FROM students WHERE class = '10A' AND city = 'Pune';

But not:

SELECT * FROM students WHERE city = 'Pune'; -- Won’t use the index efficiently

3. Indexing for JOINs

SQL · portable concepts; preserved examples identify their engine

CREATE TABLE marks (
  roll_no INT,
  subject VARCHAR(30),
  marks INT,
  FOREIGN KEY (roll_no) REFERENCES students(roll_no)
);

-- Index the join column
CREATE INDEX idx_marks_roll_no ON marks(roll_no);

-- Query using join
EXPLAIN SELECT s.name, m.subject, m.marks
FROM students s
JOIN marks m ON s.roll_no = m.roll_no;
Both tables use indexed access for join

4. Covering Index

SQL · portable concepts; preserved examples identify their engine

-- If query needs only these columns:
SELECT class, city FROM students WHERE class = '10A';

-- Create a covering index
CREATE INDEX idx_class_city_only ON students(class, city);

This helps the query get all its data directly from the index, skipping table lookup — improving speed.

When NOT to Use Indexes

  • On columns with few unique values (e.g., gender, boolean)
  • On small tables (indexes won’t help much)
  • For frequently updated columns — indexing slows down INSERT/UPDATE

How to Monitor Index Effectiveness

SQL · portable concepts; preserved examples identify their engine

EXPLAIN SELECT ... -- See if index is being used

SHOW INDEX FROM students; -- Check index usage

Index Maintenance Tips

  • Drop unused indexes using DROP INDEX
  • Use ANALYZE TABLE to update index stats
  • Test new indexes on staging before production

Real-World School Use Cases

  • Index roll_no, class in student searches
  • Composite index on (subject, marks) for report generation
  • Covering index on (class, city) for location-wise filtering

Important differences and mistakes

Leftmost-prefix behavior is a useful basic model, with engine-specific exceptions and optimizer features. Functions, collation, type conversion and expression indexes can alter eligibility. Extra indexes make insertions and updates more expensive.

Try it with the school data

Create a class/marks index, then run the class report with the same logical result.

This practice uses a separate, fresh fixture named practice_students. It does not continue the changing table state of the earlier examples.

Practice input: practice_students
roll_nonameclassmarkscity
1Aarav10A85Pune
2Diya9B70Chennai
3Sneha10A85Pune

SQL · create only these practice tables in a disposable database:

CREATE TABLE practice_students (roll_no INTEGER PRIMARY KEY, name VARCHAR(50), class VARCHAR(10), marks INTEGER, city VARCHAR(30));
INSERT INTO practice_students VALUES
(1, 'Aarav', '10A', 85, 'Pune'),
(2, 'Diya', '9B', 70, 'Chennai'),
(3, 'Sneha', '10A', 85, 'Pune');

Worked answer and reasoning

This practice uses a separate, fresh fixture named practice_students. It does not continue the changing table state of the earlier examples.

Practice input: practice_students
roll_nonameclassmarkscity
1Aarav10A85Pune
2Diya9B70Chennai
3Sneha10A85Pune

SQL · create only these practice tables in a disposable database:

CREATE TABLE practice_students (roll_no INTEGER PRIMARY KEY, name VARCHAR(50), class VARCHAR(10), marks INTEGER, city VARCHAR(30));
INSERT INTO practice_students VALUES
(1, 'Aarav', '10A', 85, 'Pune'),
(2, 'Diya', '9B', 70, 'Chennai'),
(3, 'Sneha', '10A', 85, 'Pune');

SQL · this practice variation runs with SQLite 3; the preserved examples retain their stated dialect

CREATE INDEX practice_class_marks_index ON practice_students(class, marks);
SELECT name, marks FROM practice_students WHERE class = '10A' ORDER BY marks DESC, roll_no;
Expected query result
namemarks
Aarav85
Sneha85

The index offers a class-first access path. Whether this fixture uses it is an observation from the plan, not a promised outcome of creating it.

Check your understanding

Why can the order of columns in a composite index matter?
Choose one answer. You can try again.

Answer and explanation

It affects the leading lookup and ordering paths available to the optimizer.

The index offers a class-first access path. Whether this fixture uses it is an observation from the plan, not a promised outcome of creating it.

Use the idea independently

Index optimization chooses a small, useful set of indexes for actual filters, joins and ordering needs, while accounting for write and storage costs.

The index offers a class-first access path. Whether this fixture uses it is an observation from the plan, not a promised outcome of creating it.

Continue your understanding with Indexes and Read Execution Plans.

Source for the engine-specific behavior: MySQL 8.4 reference documentation.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: SQL Injection and Security — Protecting Your Database from Malicious Input →