index

Published 2026-07-29 10:51 Updated 2026-07-29 10:51 1436 words 8 min read ... Page views

This article systematically introduces the concept, types, storage structure, creation and use methods of database indexes, as well as index design and optimization principles. It is emphasized that although indexes can improve query efficiency, they need to be reasonably designed to avoid over-use, and should be created carefully in scenarios where data updates are frequent or discrimination is low. At the same time, combining EXPLAIN analysis execution plans, understanding the leftmost prefix principle of composite indexes, and avoiding functional operations or NULL processing on index columns are the key to achieving efficient queries.

index

The concept of index

An index is a data structure maintained by a database to improve the efficiency of data retrieval. It is similar to a book catalog and can help the database reduce the number of data rows that need to be scanned.

Indexing can increase query speed, but it also takes up extra storage space and increases maintenance costs when adding, modifying, and deleting data. Therefore, the more indexes are not the better, and should be designed based on actual query conditions.

Common index types

primary key index

The primary key of a table automatically creates a primary key index. The primary key value must be unique and cannot be NULL.

unique index

Unique indexes are used to restrict column values from being duplicate. MySQL’s unique index usually allows multiple NULLs to appear, and the specific behavior also depends on the database version and column definition.

general index

Ordinary indexes are mainly used to improve query speed and are not responsible for ensuring data uniqueness.

compound index

A composite index consists of multiple columns. For example, when the index column order is job_id and salary, the following query conditions can usually be supported:

where job_id = ?
where job_id = ? and salary >= ?

However, when using only salary queries, the leftmost column of the composite index cannot be effectively utilized. This is the left-most prefix principle for composite indexes.

full-text index

Full-text indexing is used for text content retrieval. MySQL can combine MATCH() and AGAINST() for full-text query, and Chinese full-text search is often used in conjunction with ngram word segmentation.

Storage structure of index

MySQL’s InnoDB storage engine mainly uses B+ trees to organize ordinary indexes and primary key indexes.

B+ trees have the following characteristics:

  • Data key values are organized in an orderly manner.
  • The tree is low in height and is suitable for disk and paging storage.
  • Ordered connections between leaf nodes, suitable for range queries.
  • You can reduce the number of disk page accesses when querying.

Hash structures are good for equivalence lookups, but not for range queries and sorting. The regular index of InnoDB is not a regular hash index.

Create and delete indexes

Create a general index

create index employee_index1
on employee(first_name);

Create a composite index

create index employee_index2
on employee(job_id, salary);

creates a unique index

create unique index employee_index3
on employee(phone_number);

create a full-text index

alter table employee
add address varchar(255);

create fulltext index employee_index_addr
on employee(address)
with parser ngram;

Use full-text indexed queries

Natural language model query:

select address
from employee
where match(address) against('大庆');

Boolean mode query:

select address
from employee
where match(address)
against('+黑龙江 -大庆' in boolean mode);

delete the index

drop index employee_index1 on employee;

You can also delete indexes through ALTER TABLE:

alter table employee
drop index employee_index1;

Index differences between InnoDB and MyISAM

InnoDB

InnoDB uses clustered indexes to organize table data. The leaf nodes of the primary key index hold the complete row data, and the leaf nodes of the secondary index hold the primary key value.

When querying non-indexed columns through a secondary index, the database usually first obtains the primary key from the secondary index, and then finds the complete row through the primary key index. This process is often called table return.

If the table does not have an explicit primary key, InnoDB selects the appropriate unique non-null index, or creates internal hidden row identifiers to organize clustered indexes. Therefore, InnoDB tables should usually proactively design concise and stable primary keys.

MyISAM

MyISAM separates index and data files. The index leaf node stores the physical address of the data record. There is no difference in data positioning methods between the primary key index and the ordinary index between the InnoDB clustered index and the secondary index.

InnoDB supports transaction and row-level locking and is MySQL’s default storage engine. MyISAM does not support transactions, and modern business systems often use InnoDB first.

Use EXPLAIN to analyze queries

You can add EXPLAIN or DESC before the query statement to view the execution plan selected by the optimizer.

explain
select *
from employee
where first_name = 'Tom';

Common fields include:

FieldDescription
typeTable access method, usually gradually improving
possible_keysPossible Index
keyActual selected index
key_lenIndex length used
rowsExpected number of rows scanned
ExtraAdditional execution information

Common values in type include ALL, index, range, ref, eq_ref, and const. In general, we should focus on ALL full table scanning on large tables, but we cannot judge whether SQL is reasonable based on just a single field.

eq_ref is commonly used in scenarios where connection conditions use primary keys or unique non-empty indexes. ref is common in scenarios where ordinary indexes are used for equivalent queries.

Slow query positioning

SQL optimization usually locates the problem first, analyzes the execution plan, and finally adjusts the SQL or index.

Open slow query log

Slow query logs can be set in the MySQL configuration file. Configuration file locations may differ for different systems and installation methods.

slow_query_log=ON
slow_query_log_file=WW-slow.log
long_query_time=10

After modifying the configuration, you usually need to restart the MySQL service or use the corresponding dynamic system variables. The production environment should set a reasonable threshold based on business conditions, rather than fixed use for ten seconds.

Analyze slow SQL

After locating the slow SQL, use EXPLAIN to check the index selection, join order, expected scan rows, and whether temporary tables or extra sorting appear.

SQL and index optimization principles

Reasonably design composite index

The column order of a compound index affects availability. Design should incorporate equivalence conditions, range conditions, sorting and grouping requirements rather than just looking at individual query fields.

Avoid unnecessary operations on index columns

The following conditions may make it difficult for ordinary indexes to directly locate:

where salary + 1000 > 8000

A more appropriate way to write it would be:

where salary > 7000

Avoid unnecessary functional processing of index columns

where year(create_time) = 2026

Can be rewritten to range query:

where create_time >= '2026-01-01'
and create_time < '2027-01-01'

Correct understanding of IN and EXISTS

IN is not necessarily slower than EXISTS, and the optimizer may convert the two into similar execution plans. Selection should be combined with data volume, index and EXPLAIN results rather than mechanical replacement.

Handle NULL with caution

When business implications permit, NOT NULL and reasonable default values can be used to simplify data processing. However, you cannot arbitrarily replace the real “unknown” state with meaningless values for index optimization.

Avoid meaningless full-column queries

Only querying columns needed by the business can reduce the amount of data transmitted and returned to tables by the network, and also have the opportunity to form an overlay index.

select employee_id, first_name
from employee
where first_name = 'Tom';

Select an index column with the right degree of discrimination

A large number of columns with duplicate values are indexed separately, and the benefits may be low. The prefix index is suitable for long strings, but the prefix length needs to be selected based on discrimination and query requirements.

create index employee_email_prefix
on employee(email(12));

Design indexes for joining, sorting, and grouping

Connected fields should have consistent data types and be indexed based on query frequency. Foreign key constraints and indexes are two concepts. Foreign keys are used to ensure referential integrity, and indexes are used to improve access efficiency. When InnoDB creates foreign keys, it requires that relevant columns have available indexes, but it cannot be simply understood as “if there are foreign keys, the query must be the fastest.”

Avoid blindly creating indexes

The following categories are usually not suitable for establishing a common index separately:

  • A table with a small amount of data.
  • Columns that are updated frequently and are rarely queried.
  • Columns with extremely low discrimination and no other combined query value.
  • Columns that never appear in query, join, sort, or group criteria.

Whether index is ultimately needed should be based on the real query and execution plan.

If you enjoyed this, leave a comment~

... Page views
© 2026 跨越星轨的客 @Hoshiumi
Powered by theme astro-koharu · Inspired by Shoka