Databases 38 min read

Master MySQL Performance: Indexes, Explain Plans, and Optimization Tips

This comprehensive guide explains MySQL's architecture, storage engines, and the critical role of indexes, walks through the SQL parsing process, details how to read and interpret EXPLAIN output, and provides practical optimization examples for single‑table and multi‑table queries.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Master MySQL Performance: Indexes, Explain Plans, and Optimization Tips

Introduction

This article provides a practical guide to MySQL performance tuning, focusing on the architecture of MySQL, the role of indexes, how to interpret EXPLAIN output, and concrete optimization techniques.

1. MySQL Basic Architecture

MySQL consists of a client layer (command‑line, Workbench, Navicat, etc.) and a server layer that is split into the SQL processing layer and the storage‑engine layer. After a query is parsed, the optimizer generates an execution plan, the result set may be cached in the query cache, and finally the data are sent back to the client.

Key commands to inspect the environment:

SHOW ENGINES;
SHOW VARIABLES LIKE "%storage_engine%";

Creating a table with a specific engine:

CREATE TABLE tb (
    id   INT(4) AUTO_INCREMENT,
    name VARCHAR(5),
    dept VARCHAR(5),
    PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2. SQL Optimization

Why Optimize SQL?

Complex joins, sub‑queries or large result sets can cause execution times of minutes or hours. Writing efficient SQL reduces resource consumption and improves user experience.

SQL Writing vs. Parsing Process

Writing order (the order you type the statement):

SELECT DISTINCT ... FROM ... JOIN ... ON ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ...

Parsing order (how MySQL rewrites the statement internally):

FROM ... ON ... JOIN ... WHERE ... GROUP BY ... HAVING ... SELECT DISTINCT ... ORDER BY ... LIMIT ...

For a detailed description of the parsing steps see: https://www.cnblogs.com/annsshadow/p/5037667.html

Indexes are the Core of Optimization

MySQL uses B‑Tree (specifically B+‑Tree) structures for most indexes. An index works like a dictionary, allowing rapid location of rows.

Creating common index types:

CREATE INDEX dept_index ON tb(dept);
CREATE UNIQUE INDEX name_index ON tb(name);
CREATE INDEX dept_name_index ON tb(dept, name);

How Indexes Work

Without an index MySQL performs a full table scan. With an index it traverses the B+‑Tree, dramatically reducing the number of row look‑ups.

Index Drawbacks

Indexes consume additional memory or disk space, especially on large tables.

Low‑cardinality columns, frequently updated columns, or columns rarely used in queries are poor candidates for indexing.

Indexes speed up reads but slow down INSERT/UPDATE/DELETE because both the table and the index must be modified.

Index Benefits

Reduced I/O and CPU usage for read‑heavy workloads.

Because index entries are stored in sorted order, ORDER BY can be satisfied without an extra sort step.

3. Index Classification and Creation

Index Types

Single‑value index (普通索引)

Unique index (唯一索引)

Composite index (复合索引)

Creating Indexes

SQL syntax:

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

Alternative using ALTER TABLE:

ALTER TABLE table_name ADD INDEX index_name(column);

Primary keys are indexed automatically; they differ from unique indexes because primary keys cannot be NULL.

Dropping and Querying Indexes

DROP INDEX index_name ON table_name;
SHOW INDEX FROM table_name;

4. Exploring SQL Performance Issues

Manual tuning relies on EXPLAIN to view the optimizer's execution plan. The optimizer may also rewrite queries automatically, which can interfere with manual tuning.

Key Columns in EXPLAIN Output

id : step identifier

select_type : query type (SIMPLE, PRIMARY, SUBQUERY, DERIVED, UNION, etc.)

table : table name

type : join type (system, const, eq_ref, ref, range, index, ALL)

possible_keys : indexes that could be used

key : index actually used

key_len : length of the used index (helps determine whether a composite index is fully applied)

rows : estimated number of rows examined

Extra : additional information such as using filesort, using temporary, using index, using where,

impossible where

Typical EXPLAIN Scenarios

Simple SELECT EXPLAIN SELECT * FROM teacher; Derived (UNION) query

EXPLAIN SELECT cr.cname FROM (
    SELECT * FROM course WHERE tid=1
    UNION
    SELECT * FROM course WHERE tid=2
) cr;

Using Filesort

If the ORDER BY column differs from the indexed column, MySQL adds using filesort, which incurs an extra sorting step.

EXPLAIN SELECT * FROM test02 WHERE a1='' ORDER BY a1;

When ordering by a different column, using filesort appears:

EXPLAIN SELECT * FROM test02 WHERE a1='' ORDER BY a2;

Using Temporary

GROUP BY that requires a temporary table shows using temporary in the Extra column.

EXPLAIN SELECT a1 FROM test02 WHERE a1 IN ('1','2','3') GROUP BY a1;

Index Coverage ( using index )

If all columns referenced by the query are present in the index, MySQL can satisfy the query using only the index, avoiding a table lookup.

EXPLAIN SELECT a1, a2 FROM test02 WHERE a1='' AND a2='';

Using Where

When an index can satisfy part of the condition but additional columns are needed, MySQL adds using where to indicate a table lookup.

Impossible Where

If the WHERE clause is always false, the plan shows impossible where and returns no rows.

EXPLAIN SELECT a1 FROM test02 WHERE a1='a' AND a1='b';

5. Optimization Examples

Single‑Table Optimization

Create a table and a composite index, then query with conditions that match the index order. The optimizer will use the index efficiently regardless of the order of the predicates.

CREATE TABLE test03 (
    a1 INT NOT NULL,
    a2 INT NOT NULL,
    a3 INT NOT NULL,
    a4 INT NOT NULL
);
CREATE INDEX a1_a2_a3_test03 ON test03(a1, a2, a3);
EXPLAIN SELECT a3 FROM test03 WHERE a1=1 AND a2=2 AND a3=3;

Multi‑Table Optimization

When joining tables, place the smaller (driving) table on the left and index the join columns as well as any filter columns.

CREATE TABLE teacher2 (
    tid INT PRIMARY KEY,
    cid INT NOT NULL
);
CREATE TABLE course2 (
    cid INT,
    cname VARCHAR(20)
);
CREATE INDEX cid_teacher2 ON teacher2(cid);
CREATE INDEX cname_course2 ON course2(cname);
EXPLAIN SELECT *
FROM teacher2 t
LEFT JOIN course2 c ON t.cid=c.cid
WHERE c.cname='java';

Guidelines to Avoid Index Loss

Never apply functions, type casts, or arithmetic on indexed columns (e.g., authorid*2=1).

Avoid !=, <>, IS NULL, or OR on indexed columns; they often cause the index to be ignored.

Place range conditions ( IN, >, <) at the end of the predicate list to keep preceding indexes usable.

For composite indexes follow the left‑most prefix rule; do not skip columns or change their order.

Use LIKE 'prefix%' instead of LIKE '%pattern%' to allow index usage.

Prefer EXISTS when the sub‑query returns many rows, and IN when the outer query is large.

Order‑By Optimization

To avoid using filesort, order by columns that are part of the index and use the same sort direction (ASC/DESC). If the sort buffer is too small, MySQL may fall back to a double‑pass sort. The buffer size can be increased:

SET max_length_for_sort_data = 1024;

Additional Practical Tips

Read EXPLAIN output carefully; the type column indicates how efficiently rows are accessed.

Composite indexes should match the order of predicates in the WHERE clause.

If using index appears, the query is fully covered by the index and avoids table reads.

Regularly drop unused indexes to reduce write overhead and prevent optimizer confusion.

Systematic index design, a solid understanding of EXPLAIN fields, and incremental testing can lead to substantial MySQL performance gains.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

mysqlindexesexplainDatabase Performance
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.