How to Create an Index in MySQL:
A Complete Guide

As databases continue to grow and evolve, data storage and management become increasingly complex and demanding. The processing of data requires more time, but it is critical to have the possibility to retrieve the necessary data quickly and efficiently.

The most common option for resolving this challenge is using indexes that directly refer to the necessary data within the database tables. This article will explore the types, characteristics, and applications of indexes in MySQL.

Why use indexes in MySQL?

The main issue with querying large tables that don't have indexes is that the query needs to scan the entire table until it finds the records that meet the conditions. This often takes a lot of time and resources. As tables become larger and more complex, queries become more problematic. Indexes help resolve this issue by creating order in a table - a data structure with references to the necessary information.

Indexes are exceptionally helpful in the following scenarios:

  • When queries include ORDER BY for sorting records.
  • When queries include range conditions like BETWEEN, <, <=, >, or >=.
  • When queries contain JOIN clauses (indexes should be on the columns used in joins).
  • When queries deal with text-based searches.
  • When all columns in a query are part of an index, allowing the query to use the index instead of scanning the target table.

On the other hand, indexes are separate database objects, and the more columns are included in an index, the more space it consumes. Additionally, indexes increase table structure complexity and can complicate database design and administration. Therefore, implementing an index is not a universal solution and should be considered carefully for each specific case.

There are situations where it's better to avoid indexes:

  • With small tables.
  • With frequently updated tables.
  • With columns not used in WHERE clauses.

Next, let's examine how to create indexes in MySQL.

Syntax for MySQL CREATE INDEX statement

In MySQL, indexes are created using the CREATE INDEX statement. The basic syntax of the query is:

CREATE INDEX index_name  
ON table_name (column1, column2, ...);  

The parameters are:

  • index_name - the name of the created index, which must be unique within a table but can be repeated across tables in the database.
  • table_name - the name of the table where the index is created.
  • column1, column2, ... - the column or the list of columns included in the index.

When an index is no longer needed, it can be removed using the DROP INDEX statement:

DROP INDEX index_name 
ON table_name;  

Our next step is to explore the different types of indexes supported in MySQL.

Types and examples for MySQL CREATE INDEX

MySQL indexes can be created on both single and multiple columns. These indexes can be either unique or non-unique, depending on the specific requirements of each use case. In this section, we will explore different types of indexes and demonstrate how they are used in real-world scenarios.

To illustrate our cases, we will use the popular MySQL test database, sakila, and dbForge Studio for MySQL, a comprehensive IDE for MySQL and MariaDB databases.

Single-column indexes

A single-column index is the simplest and most common index type in MySQL. It is created on a single column in a table and is used to speed up queries that filter results based on values from that specific column.

The syntax for creating a single-column index on a table is:

CREATE INDEX index_name  
ON table_name(column_name);

To create a single-column index on the last_name column in the actor table from the sakila database, use the query:

CREATE INDEX idx_actor_last_name  
ON actor(last_name);  

To verify that the index was created, use the SHOW INDEX command:

SHOW INDEX FROM actor;  

Create a single-column index in MySQL

Composite indexes

In many cases, you might need to include multiple columns in an index, especially if you use those columns frequently together in queries, particularly for large tables with many columns. A multiple-column index (a composite index) combines values from multiple columns into a single index, allowing MySQL to find data based on several criteria at once.

Such indexes are often a better solution than several single-column indexes as they ensure faster query execution, reduce storage space, and minimize the number of disk I/O operations.

To create a composite index in MySQL, you need to include all the necessary columns (up to 16) in the CREATE INDEX statement as follows:

CREATE INDEX index_name 
ON table_name (column1, column2, ...);
Note
The order of columns in the index is essential, as it is impossible to omit some columns or read them out of order when using the composite index.

Suppose we frequently query the rental table using both customer_id and rental_date. A composite index on these columns can speed up such queries. Without an index, the query takes 0.124 seconds.

SELECT 
*
FROM rental
WHERE customer_id = 5
ORDER BY rental_date DESC;

Results delivered for non-indexed columns

We create a composite index on the rental table:

CREATE INDEX idx_customer_rental_date 
ON rental (customer_id, rental_date);

Repeat the search, and we can see the result delivered in 0.004 seconds

Results delivered for columns with a composite index

Unique indexes

A unique index in MySQL ensures that values in an indexed column or multiple columns are unique across all rows in a table. It does not allow any duplicates in a column even if it is not a primary key.

You can create a unique index when you create a table, or you can add it later using the ALTER TABLE statement. It can be a single-column index or a composite index (the combination of records in several columns must be unique then). A unique index allows NULL values in indexed columns.

To create a unique index, use the following query:

CREATE UNIQUE INDEX index_name 
ON table_name (column1, column2, ...);

In our test case, the customer table contains customer details, including their email addresses. We want to use the email addresses in the unique index, as these values must be unique for each customer.

CREATE UNIQUE INDEX idx_unique_customer_email 
ON customer (email);

Without an index established, the search takes 0.117 seconds:

SELECT
  *
FROM customer
WHERE email = 'WADE.DELVALLE@sakilacustomer.org';

Search results for customers in a non-indexed column

When we rerun the search having a unique index on the column, we can get the results delivered within 0.004 seconds:

Search results for customers with a single-column unique index

Another example involves a unique composite index. In the rental table, each inventory item can only be rented once at a given time by a specific customer. Searching without an index brings us results within 0.116 seconds.

SELECT
  *
FROM rental
WHERE inventory_id = 1498
AND customer_id = 64
AND rental_date = '2005-05-31 00:46:31';

Searching for records based on several columns with no unique index

We can create a composite unique index on inventory_id, customer_id, and rental_date:

CREATE UNIQUE INDEX idx_unique_rental 
ON rental (inventory_id, customer_id, rental_date);

Performing the same search now delivers results in 0.003 seconds.

Searching for records based on several columns with a unique composite index

Full-text indexes

A full-text index in MySQL allows you to perform text searches in InnoDB tables (starting from version 5.6) with CHAR, VARCHAR, and TEXT columns. You can use full-text search functions like MATCH() and AGAINST() to query records efficiently within these indexes.

Full-text indexes simplify searching for textual data in articles, blogs, product descriptions, forum posts, chat applications, FAQ posts, documents, logs, job descriptions, and so on. As such resources are frequently updated, it is essential to re-index such columns regularly.

The query to create a full-text index is:

CREATE FULLTEXT INDEX index_name
ON tbl_name(column1, column2,...);

Let's create a full-text index in the film_text table:

CREATE FULLTEXT INDEX idx_film_description
ON film_text (description);

To search for films containing the phrase 'emotional drama' in their descriptions, use the following query:

SELECT
  film_id,
  title,
  description
FROM film_text
WHERE MATCH(description) AGAINST('emotional drama' IN NATURAL LANGUAGE MODE);

As you can see, results are delivered within 0.016 seconds:

Results for searching with a full-text index

Spatial indexes

Spatial indexing in MySQL allows you to search for spatial data, such as points, lines, and polygons, and efficiently retrieve and filter results based on their geometrical properties.

By applying spatial indexes, you can execute queries that involve spatial data much faster, perform complex data analysis, and handle larger volumes of spatial data much more efficiently.

Let us see how this works in a real-world scenario. As the sakila database does not contain spatial data, we have modified it and created a new test table called it customer_temp. It contains the data from the customer table with additional latitude and longitude columns and a column named location of type GEOMETRY, which stores the geographical data (latitude and longitude). The POINT data type is used to represent the location, and the values stored in that column are populated from the values of existing latitude and longitude columns.

CREATE TABLE sakila.customer_temp_new (
  customer_id smallint UNSIGNED NOT NULL DEFAULT 0,
  store_id tinyint UNSIGNED NOT NULL,
  first_name varchar(45) NOT NULL,
  last_name varchar(45) NOT NULL,
  email varchar(50) DEFAULT NULL,
  city varchar(50) DEFAULT NULL,
  latitude decimal(10, 6) DEFAULT NULL,
  longitude decimal(10, 6) DEFAULT NULL,
  location POINT
);

A test table created to explore the spatial index work

Let's say we want to find customers within a 50 km radius of a specific point. We'll use ST_Distance_Sphere to calculate the distance between points.

SELECT
  customer_id,
  first_name,
  last_name,
  city,
  latitude,
  longitude,
  ST_ASTEXT(location) AS location
FROM sakila.customer_temp
WHERE ST_DISTANCE_SPHERE(location, ST_GEOMFROMTEXT('POINT(129.7222 33.1592)')) <= 50000;

The query takes 0.105 seconds to complete.

Results delivered without a spatial index

Now, let us see how it works with the spatial index added to the location column.

Important!
MySQL does not support creating spatial indexes as a standalone statement. A spatial index must be created inside a CREATE TABLE statement or added later using ALTER TABLE.

We use the below statement to add a spatial index to our test table.

ALTER TABLE sakila.customer_temp 
ADD SPATIAL INDEX (location);

Rerun the query. The result delivery takes 0.004 seconds.

Results delivered with a spatial index

MySQL CREATE INDEX vs. ALTER TABLE ADD INDEX

In the above scenarios, we demonstrated the usage of both CREATE INDEX and ALTER TABLE ADD INDEX statements to create indexes in MySQL. However, these two approaches have different contexts and use cases. Below, we have compiled a table to review the specific features and differences in usage of these two statements.

Feature CREATE INDEX ALTER TABLE ADD INDEX
Context A standalone statement for adding indexes. A part of ALTER TABLE for schema modifications.
Table modification Does not modify the table structure. Modifies the table structure.
Common usage Adding an index independently. Adding an index as part of other schema changes.
Complexity Simpler, standalone index creation. Changing different aspects of the table schema.
Atomicity Index creation is independent of other changes. Index creation is a part of the table modification.

Common mistakes when using indexes

As we already defined, indexing is a powerful optimization technique for query performance. However, improper use can slow performance down, increase resource usage, and cause additional complexity in maintaining databases. Let us consider the most common mistakes when using indexes and define how to avoid them.

Too many indexes on a table

Over-indexing can affect the standard UPDATE, INSERT, and DELETE operations significantly because MySQL has to maintain the indexes whenever data is modified. While indexes improve query performance, each index requires storage space, and the more indexes you set, the more space is taken, which impacts the performance.

To avoid this trouble, analyze your queries and define which of them require more indexes. Limit the number of existing indexes and remove the unnecessary ones. dbForge Studio for MySQL offers its Query Profiler feature that helps you tune MySQL queries and investigate query performance issues. In particular, the EXPLAIN plan provides you with in-depth stats data for each particular query, so you can define bottlenecks and resolve them effectively.

Query Profiler in dbForge Studio for MySQL

Incorrect order of columns in composite indexes

The order of columns in the index can affect query performance. Indexes are optimized for queries that match the columns in the same order they appear in the index. Incorrect ordering can lead to poor performance for queries that don't utilize the index effectively.

Ensure that columns used in the WHERE, JOIN, or ORDER BY clauses appear first in the index. The column that contains the most unique values must come first in the index. Analyze your queries with the EXPLAIN plan to understand which columns are used and adjust your index ordering accordingly.

Absence of appropriate index usage monitoring

Indexes often become less effective or irrelevant over time. As a result, the system must manage these unused indexes, leading to unnecessary overhead and a degrade in overall performance.

The recommendations remain the same: regularly review all existing indexes to determine which are actively used and which have become obsolete. Unused indexes should be removed, while active ones should be optimized for better performance.

Creating and using MySQL indexes with dbForge Studio

We used dbForge Studio for MySQL to demonstrate the use of different indexes. The queries were composed using the MySQL Code Editor and executed against the database. The Studio offers numerous coding assistance features, including code autocompletion, formatting, debugging, and more. Additionally, we showcased how dbForge Studio helps with query analysis, enabling users to detect issues and optimize performance. However, these are just a few examples of its powerful capabilities. As a comprehensive IDE, dbForge Studio provides a complete toolset for database development, management, and administration, covering everything from writing code to version control.

One of dbForge Studio's most valuable features is its visualization capability, allowing users to perform many database tasks in a graphical interface, including index management. The Table Designer helps you create and manage indexes with just a few clicks.

  • 1. In the Database Explorer, right-click the desired table and select Open Editor. Navigate to the Indexes tab to see all indexes associated with the table. You can create new indexes or remove existing ones from this tab.
  • Open Table Designer

  • 2. Click Add non-unique index or Add unique index, depending on your goal. Specify the index name, type, and columns to be included. dbForge Studio generates an SQL script in real-time to create the index, which you can use or modify as needed.
  • Add and configure a new index in a visual mode

  • 3. To delete an index, select the necessary index and click Remove Index.
  • Remove an index in a visual mode

  • 4. Click Apply Changes to finalize the task of creating or removing the index.

Conclusion

Indexes are powerful tools that make working with databases much more ordered and efficient. Without them, retrieving data from large databases quickly and accurately would be nearly impossible. That's why it is essential to understand the different types of indexes available in MySQL (or any other database management system), how they function, how to create them, and how to maintain them for optimal performance.

dbForge Studio for MySQL is a toolset designed to simplify database management in MySQL and MariaDB. Its features help you perform all daily tasks, providing a single solution for various database challenges. An intuitive GUI allows you to switch to visual mode, making configuration and execution easier without manual coding.

You can download dbForge Studio for MySQL and test its capabilities in real-world scenarios. A fully functional 30-day free trial is available, so you can explore its full potential under actual workloads.

FAQ

What is the purpose of creating an index in MySQL?
The primary purpose of an index in MySQL is to improve query performance. Instead of physically rearranging table data, indexes create references that help MySQL quickly locate and retrieve the required information. This improves efficiency, allowing the database to find and deliver data much faster.
Are there any drawbacks or potential issues when creating too many indexes in a table?
Using too many indexes on a table can degrade performance. Although indexes are not visible, they are physical database objects that consume disk space. The more indexes you create, the more space they require. Additionally, every INSERT, UPDATE, or DELETE operation requires index updates. When a table has too many indexes, these updates become resource-intensive, leading to slower performance.
Can I create an index on an existing table without modifying the data?
Indexes do not affect the data in any way, they only create references to the data. The CREATE INDEX statement does not involve any table modifications.
How do I delete or modify an existing index in MySQL?
In MySQL, you cannot modify an existing index directly. Instead, you must first delete it and then create a new one with the desired settings. To remove an index, use the DROP INDEX command:

DROP INDEX index_name ON table_name;

After that, use the CREATE INDEX command to define the new index.
Can tools like dbForge Studio help with creating and managing indexes in MySQL?
dbForge Studio for MySQL offers a variety of features to help you work with indexes. You can create or drop indexes using SQL commands in the SQL Editor, where you can easily write and execute queries. Alternatively, you can use the visual Table Editor to modify a database table. The Indexes tab in the Table Editor provides detailed information about the existing indexes in a table and allows you to create new indexes with just a few clicks. You can also delete indexes from this tab.

dbForge Studio for MySQL

The most intelligent tool for MySQL development and management