mysql索引优化从哪里入手_mysql调优步骤说明

来源:这里教程网 时间:2026-02-28 20:45:13 作者:

先看慢查询,再查执行计划——这是 MySQL 索引优化唯一靠谱的起点。 没有慢 SQL 日志和

EXPLAIN
输出,所有“加索引”“改字段”的操作都是蒙眼贴膏药。

从慢查询日志定位真实瓶颈

线上库不开启慢查询日志,等于开车不看油表。默认它关着,必须手动打开:

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1; -- 超过1秒记为慢SQL
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

关键点:

long_query_time
建议设为 1(秒),太低会刷屏,太高漏掉隐患;
日志路径需确保 MySQL 进程有写权限,否则静默失败; 别只盯单条 SQL 的耗时——要关注 频次 × 平均耗时,高频中等耗时的语句往往比低频超长语句更伤性能; 注意区分是“锁等待”还是“真慢”,
Rows_examined
Lock_time
在日志里都带出来,别只看
Query_time

用 EXPLAIN 看懂索引到底用没用上

对慢 SQL 执行

EXPLAIN
,重点盯三列:
type
key
Extra

type = ALL
:全表扫描,紧急加索引或重构查询;
key = NULL
:明明建了索引却没走,大概率是
WHERE
条件用了函数、隐式类型转换或
OR
拆分失效;
Extra
出现
Using filesort
Using temporary
:排序/分组没走索引,得补
ORDER BY
字段到复合索引末尾;
key_len
值比预期小:说明只用了复合索引前缀,检查
WHERE
是否满足最左前缀法则。

示例:

EXPLAIN SELECT name, age FROM user_info WHERE name = 'xys' AND age > 20 ORDER BY age;

理想情况:

key = name_index
(假设你建的是
(name, age)
复合索引),
Extra
filesort
;如果
key = NULL
,就该查查
name
字段是不是被
UPPER(name)
包裹了。

建索引不是越多越好,而是“刚好够用”

索引是双刃剑:读快了,写就慢;空间占了,缓存就挤。建之前问自己三个问题:

这个字段在
WHERE
JOIN
ORDER BY
GROUP BY
里高频出现吗?没出现就别建;
它的基数(distinct 值数量)够高吗?比如
status
只有 '0'/'1',建索引几乎无效;
是否能合并?比如已有
(a, b)
索引,就别单独再建
a
单列索引——它已被覆盖。

常见误操作:

VARCHAR(255)
字段直接建全文索引——除非真做模糊搜索,否则优先考虑前缀索引:
INDEX idx_name (name(10))
DATETIME
字段上建单列索引却总查
DATE(create_time)
——函数导致索引失效,应改用范围查询:
create_time >= '2025-12-01' AND create_time ;
TEXT
或大
JSON
字段建普通索引——MySQL 不支持,得用生成列 + 索引或全文索引。

索引维护比创建更重要

索引不是一劳永逸。InnoDB 的 B+Tree 在大量增删后会碎片化,

SELECT
效率下降,但
SHOW INDEX
看不出异常:

定期检查索引碎片率:
SELECT table_name, data_free / data_length AS frag_ratio FROM information_schema.tables WHERE table_schema = 'your_db';
,> 0.3 就该考虑重建;
重建索引别用
DROP + CREATE
——锁表。用
ALTER TABLE t ENGINE=InnoDB;
(在线 DDL,MySQL 5.6+ 支持);
删除无用索引前,先用
sys.schema_unused_indexes
视图(需启用 performance_schema)确认它真没人用;盲目删可能让某条夜间报表 SQL 突然变慢十倍。

最后提醒一句:索引优化解决不了设计缺陷。如果一张表连主键都没有、或者

JOIN
总是跨 5 张大表,加再多索引也只是延缓崩溃——该拆表拆表,该加冗余加冗余,别拿索引当创可贴。

相关推荐