DEV Community

Sadiul Hakim
Sadiul Hakim

Posted on

Database index tutorial with MYSQL

1. What Is an Index?

An index in a database is like the index in a book — it helps you find data faster without scanning the entire table.

  • Without index → MySQL scans every row (Full Table Scan).
  • With index → MySQL jumps directly to matching rows using an internal data structure (usually a B-Tree).

In simple words:
Index = a data structure (B-Tree or Hash) that stores sorted key values and pointers to table rows.


2. Why Do We Need It?

Indexes speed up read operations such as:

  • SELECT with WHERE, JOIN, ORDER BY, GROUP BY
  • Searching/filtering large tables

They reduce disk I/O and CPU time.

Advantages:

  • Faster reads
  • Faster joins
  • Better query optimization

Disadvantages:

  • Slower writes (INSERT, UPDATE, DELETE) because index also needs updating
  • Consumes extra disk space
  • Too many indexes confuse the query planner

3. When to Use and When NOT to Use

Use Index When Avoid Index When
Column used in WHERE, JOIN, ORDER BY, or GROUP BY Column with low selectivity (e.g., gender = 'M' or 'F')
Frequently searched column (e.g., email, username) Column that is frequently updated
Foreign keys and primary keys Small tables (index overhead > benefit)
Range queries (BETWEEN, <, >) Temporary or staging tables

Rule of Thumb:
Index columns that are used to filter or join large datasets.


4. How Index Works Internally (Simplified)

MySQL (InnoDB) stores data in B+Tree form:

        [50]
       /    \
   [20]      [70]
   /  \      /  \
[10][30]  [60][80]
Enter fullscreen mode Exit fullscreen mode
  • The index keys are sorted.
  • Searching is O(log n) instead of O(n).
  • When you create an index on a column, MySQL maintains this structure automatically.

5. Types of Indexes in MySQL

Type Description Example
PRIMARY KEY Unique identifier for each row id
UNIQUE INDEX Prevents duplicate values email
INDEX (NON-UNIQUE) For faster lookups name, created_at
FULLTEXT INDEX For text search (MATCH ... AGAINST) content
COMPOSITE INDEX Index on multiple columns (first_name, last_name)
SPATIAL INDEX For geo data (GIS) geometry

6. Practical Examples (MySQL)

Let’s use a sample table:

CREATE TABLE users (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(100),
  email VARCHAR(100),
  age INT,
  city VARCHAR(100),
  created_at DATETIME
);
Enter fullscreen mode Exit fullscreen mode

6.1 Creating Indexes

-- Normal index
CREATE INDEX idx_username ON users(username);

-- Unique index
CREATE UNIQUE INDEX idx_email_unique ON users(email);

-- Composite index
CREATE INDEX idx_city_age ON users(city, age);
Enter fullscreen mode Exit fullscreen mode

6.2 Dropping Index

DROP INDEX idx_username ON users;
Enter fullscreen mode Exit fullscreen mode

6.3 Viewing Indexes

SHOW INDEX FROM users;
Enter fullscreen mode Exit fullscreen mode

7. How to Measure Performance

Without Index

EXPLAIN SELECT * FROM users WHERE email = 'john@example.com';
Enter fullscreen mode Exit fullscreen mode

MySQL output shows:

type: ALL
rows: 1000000
Extra: Using where
Enter fullscreen mode Exit fullscreen mode

Means full table scan.

With Index

After adding:

CREATE INDEX idx_email ON users(email);
Enter fullscreen mode Exit fullscreen mode

Run again:

EXPLAIN SELECT * FROM users WHERE email = 'john@example.com';
Enter fullscreen mode Exit fullscreen mode

Output:

type: ref
rows: 1
Extra: Using index
Enter fullscreen mode Exit fullscreen mode

That means MySQL now uses the index and reads only matching rows.


8. Composite Index Guidelines

CREATE INDEX idx_name_city ON users(name, city);
Enter fullscreen mode Exit fullscreen mode

The order of columns matters!

Query Uses Index?
WHERE name = 'John' ✅ Yes
WHERE name = 'John' AND city = 'Paris' ✅ Yes
WHERE city = 'Paris' ❌ No (leftmost rule)

So always put the most selective column first in a composite index.


9. Common Mistakes

  1. Too many indexes → slow writes, high maintenance.
  2. Wrong order in composite index.
  3. Indexing small or low-cardinality columns (e.g., gender, status).
  4. Using function on indexed column breaks index usage:
   SELECT * FROM users WHERE LOWER(email) = 'john@example.com'; -- ❌ Index ignored
Enter fullscreen mode Exit fullscreen mode
  1. LIKE with leading wildcard disables index:
   WHERE username LIKE '%john%'  -- ❌ No index
   WHERE username LIKE 'john%'   -- ✅ Index used
Enter fullscreen mode Exit fullscreen mode

10. Advanced Tips

  • Covering Index: If all selected columns are inside the index, MySQL doesn’t touch the table:
  CREATE INDEX idx_email_city ON users(email, city);
  SELECT email, city FROM users WHERE email = 'john@example.com';
Enter fullscreen mode Exit fullscreen mode

→ Fully served from index.

  • Analyze and Optimize:
  EXPLAIN SELECT ...
  SHOW STATUS LIKE 'Handler_read%';
Enter fullscreen mode Exit fullscreen mode
  • Remove unused indexes:
  SELECT * FROM sys.schema_unused_indexes;
Enter fullscreen mode Exit fullscreen mode

11. Real-World Strategy

Purpose Example
Primary key id
Foreign key Index on FK column
Search field username, email, phone
Date filter (created_at) or (user_id, created_at)
Sorting Add ORDER BY columns in index

12. Summary Cheat Sheet

Task SQL
Create index CREATE INDEX idx_col ON table(col);
Unique index CREATE UNIQUE INDEX idx_col_unique ON table(col);
Composite index CREATE INDEX idx_multi ON table(col1, col2);
Drop index DROP INDEX idx_col ON table;
View indexes SHOW INDEX FROM table;
Check usage EXPLAIN SELECT ...

Top comments (0)