Skip to main content

MySQL CREATE INDEX

Introduction

In MySQL, indexes are special data structures that improve the speed of data retrieval operations on database tables. Similar to how an index in a book helps you find information quickly without reading every page, database indexes help MySQL find specific rows much faster without scanning the entire table.

The CREATE INDEX statement is used to add indexes to existing tables in MySQL. Properly configured indexes are one of the most important aspects of database performance optimization, especially for large tables and complex queries.

Understanding Indexes in MySQL

Before we dive into creating indexes, let's understand why they matter:

  • Faster data retrieval: Indexes allow the database engine to find and retrieve specific rows much faster
  • Improved query performance: Complex queries, especially those with WHERE clauses, benefit significantly from indexes
  • Enforced constraints: Unique indexes help enforce data integrity by preventing duplicate values

However, indexes also come with trade-offs:

  • They consume additional storage space
  • They slow down data modification operations (INSERT, UPDATE, DELETE)

CREATE INDEX Syntax

The basic syntax for creating an index in MySQL is:

sql
CREATE [type] INDEX index_name
ON table_name (column1, column2, ...);

Where:

  • [type] (optional) specifies the type of index (UNIQUE, FULLTEXT, SPATIAL)
  • index_name is the name you want to give to the index
  • table_name is the table that will be indexed
  • column1, column2, ... are the columns to include in the index

Types of MySQL Indexes

MySQL supports several types of indexes:

1. Regular Index

A regular index (also called a non-unique index) allows duplicate values in the indexed column.

sql
CREATE INDEX idx_lastname
ON customers (last_name);

This creates an index on the last_name column of the customers table, which will speed up queries that search or sort by last name.

2. Unique Index

A unique index ensures that all values in the indexed column(s) are distinct.

sql
CREATE UNIQUE INDEX idx_email
ON customers (email);

This creates a unique index on the email column, preventing any two customers from having the same email address.

3. Fulltext Index

A fulltext index is used for full-text searches on text columns.

sql
CREATE FULLTEXT INDEX idx_article_content
ON articles (title, content);

This enables efficient text searching within the title and content columns.

4. Spatial Index

A spatial index is used for columns that contain spatial data types.

sql
CREATE SPATIAL INDEX idx_location
ON stores (location);

This creates a spatial index on the location column to optimize queries that involve spatial operations.

5. Composite Index

A composite index spans multiple columns.

sql
CREATE INDEX idx_name
ON customers (last_name, first_name);

This creates an index on both the last_name and first_name columns, which is useful for queries that filter or sort by both columns.

Creating Indexes with Examples

Let's walk through some practical examples of creating indexes in MySQL.

Example 1: Creating a Simple Index

First, let's create a sample table:

sql
CREATE TABLE employees (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
email VARCHAR(100),
hire_date DATE,
department VARCHAR(50),
salary DECIMAL(10, 2)
);

Now, let's create an index on the department column to speed up queries that filter by department:

sql
CREATE INDEX idx_department
ON employees (department);

Example query that would benefit:

sql
SELECT * FROM employees WHERE department = 'Marketing';

With this index, MySQL can quickly locate all employees in the Marketing department without scanning the entire table.

Example 2: Creating a Unique Index

Let's ensure that employee emails are unique:

sql
CREATE UNIQUE INDEX idx_email
ON employees (email);

This will prevent inserting or updating records with duplicate email addresses:

sql
-- This will succeed
INSERT INTO employees (first_name, last_name, email, department)
VALUES ('John', 'Doe', '[email protected]', 'IT');

-- This will fail with a duplicate key error
INSERT INTO employees (first_name, last_name, email, department)
VALUES ('Jane', 'Smith', '[email protected]', 'Finance');

Example 3: Creating a Composite Index

If you frequently run queries that filter by both department and hire date, a composite index would be helpful:

sql
CREATE INDEX idx_dept_hire_date
ON employees (department, hire_date);

Example query that would benefit:

sql
SELECT * FROM employees 
WHERE department = 'Sales'
AND hire_date >= '2022-01-01';

This query will use the composite index for efficient filtering.

Creating Indexes During Table Creation

You can also define indexes when you first create a table:

sql
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
product_name VARCHAR(100),
category VARCHAR(50),
price DECIMAL(10, 2),
stock_quantity INT,
INDEX idx_category (category),
UNIQUE INDEX idx_product_name (product_name)
);

This creates a table with:

  • A primary key on the id column (which is automatically indexed)
  • A regular index on the category column
  • A unique index on the product_name column

Index Management

Checking Existing Indexes

To see all indexes on a table:

sql
SHOW INDEXES FROM table_name;

Example output:

+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| employees | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| employees | 1 | idx_dept | 1 | department | A | 0 | NULL | NULL | YES | BTREE | | |
| employees | 0 | idx_email | 1 | email | A | 0 | NULL | NULL | YES | BTREE | | |
+----------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

Dropping an Index

If you no longer need an index, you can remove it:

sql
DROP INDEX index_name ON table_name;

For example:

sql
DROP INDEX idx_department ON employees;

Best Practices for Creating Indexes

  1. Index columns used in WHERE clauses: Columns that frequently appear in WHERE, JOIN, or ORDER BY clauses are good candidates for indexes.

  2. Consider column cardinality: Indexes work best on columns with high cardinality (many unique values). Indexing a column with only a few distinct values (like gender) may not provide much benefit.

  3. Mind the order in composite indexes: In a composite index, the order of columns matters. Place the most selective column first.

  4. Don't over-index: Each index takes up space and slows down write operations. Only create indexes that you know will improve query performance.

  5. Use EXPLAIN to verify index usage: The EXPLAIN statement shows how MySQL executes a query, including which indexes are used.

sql
EXPLAIN SELECT * FROM employees WHERE department = 'Sales';
  1. Regular maintenance: Consider rebuilding indexes periodically on tables that undergo many modifications.
sql
ALTER TABLE employees DROP INDEX idx_department;
CREATE INDEX idx_department ON employees (department);

Practical Real-World Example

Let's consider an e-commerce database with an orders table:

sql
CREATE TABLE orders (
order_id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT,
order_date DATETIME,
status VARCHAR(20),
total_amount DECIMAL(10, 2),
shipping_address TEXT,
payment_method VARCHAR(50)
);

-- Initially populate with some data
INSERT INTO orders (customer_id, order_date, status, total_amount, payment_method)
VALUES
(1001, '2023-01-15 14:30:00', 'completed', 129.99, 'credit_card'),
(1045, '2023-01-15 15:22:00', 'processing', 85.50, 'paypal'),
(1001, '2023-01-16 09:15:00', 'completed', 35.25, 'credit_card'),
(1089, '2023-01-16 11:05:00', 'cancelled', 199.99, 'bank_transfer');

As the e-commerce platform grows, the orders table will contain millions of rows. Common queries might include:

  1. Finding all orders by a specific customer
  2. Finding orders within a date range
  3. Finding orders with a specific status
  4. Combinations of the above

Let's create indexes to optimize these queries:

sql
-- Index for finding orders by customer
CREATE INDEX idx_customer_id ON orders (customer_id);

-- Index for finding orders by date
CREATE INDEX idx_order_date ON orders (order_date);

-- Index for finding orders by status
CREATE INDEX idx_status ON orders (status);

-- Composite index for finding orders by customer and date
CREATE INDEX idx_customer_date ON orders (customer_id, order_date);

Now, queries like these will be much faster:

sql
-- Find all orders for customer 1001
SELECT * FROM orders WHERE customer_id = 1001;

-- Find all orders placed on January 15, 2023
SELECT * FROM orders WHERE DATE(order_date) = '2023-01-15';

-- Find all completed orders for customer 1001
SELECT * FROM orders
WHERE customer_id = 1001 AND status = 'completed';

You can verify index usage with EXPLAIN:

sql
EXPLAIN SELECT * FROM orders WHERE customer_id = 1001;

This real-world scenario demonstrates how proper indexing can significantly improve the performance of an e-commerce application, especially during high-traffic periods such as sales events.

Summary

Creating appropriate indexes is a fundamental database optimization technique that can dramatically improve query performance in MySQL. In this guide, we've covered:

  • The basic syntax of the CREATE INDEX statement
  • Different types of indexes (regular, unique, fulltext, spatial, composite)
  • How to create indexes with practical examples
  • Best practices for effective indexing
  • How to manage and maintain indexes

Remember that while indexes can significantly speed up data retrieval, they also require additional storage space and can slow down data modification operations. Always consider the trade-offs when designing your indexing strategy.

Additional Resources and Exercises

Practice Exercises

  1. Create a books table with columns for book_id, title, author, genre, publication_date, and price. Add appropriate indexes to optimize queries that:

    • Find books by a specific author
    • Find books in a specific genre
    • Find books published after a certain date
  2. Write an EXPLAIN statement to verify that your indexes are being used correctly.

  3. Create a composite index for queries that find books by both author and genre.

Further Reading

Understanding and properly implementing indexes will help you build high-performance database applications that can scale effectively as your data grows.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)