mysql索引如何提高查询性能_mysql优化基础方法

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

为什么加了索引查询还是慢

索引不是万能的,

WHERE
条件没用上索引列、用了函数或类型隐式转换、或者查询返回大量行,都会让索引失效。比如写
WHERE YEAR(create_time) = 2023
,MySQL 无法使用
create_time
上的普通 B+ 树索引;又比如
WHERE user_id = '123'
,而
user_id
INT
类型,字符串比较会触发隐式转换,导致索引跳过。

实操建议:

EXPLAIN
查看
type
是否为
ref
/
range
key
是否显示实际使用的索引名
避免在索引列上做计算、函数调用、
LIKE '%xxx'
开头匹配
确保查询条件的数据类型和字段定义完全一致(如
INT
INT
,不是
INT
VARCHAR

复合索引的最左前缀怎么生效

MySQL 的复合索引(如

(a, b, c)
)只支持从左到右连续匹配。这意味着它可以加速
WHERE a = ?
WHERE a = ? AND b = ?
WHERE a = ? AND b = ? AND c = ?
,但对
WHERE b = ?
WHERE a = ? AND c = ?
(跳过
b
)无效。

实操建议:

把高频等值查询字段放最左,范围查询(
>
BETWEEN
)字段放中间,排序/分组字段放最后
如果常查
status
created_at
,但
status
只有 3 个值,而
created_at
高度离散,应建
(status, created_at)
而非反过来
不要盲目堆字段:超过 3 列的复合索引维护成本高,且命中率未必提升

什么时候该用覆盖索引

覆盖索引指查询所需的所有字段都包含在索引中,无需回表查聚簇索引。例如表有

id
name
email
status
,而你执行
SELECT name, email FROM users WHERE status = 'active'
,若存在索引
(status, name, email)
,就能直接从索引页拿到全部数据。

实操建议:

对高频、轻量级查询(如列表页只展示几个字段),优先考虑覆盖索引减少 I/O 注意索引大小:把大字段(如
TEXT
、长
VARCHAR
)放进索引会显著增大索引体积,得不偿失
EXPLAIN
Extra
列是否含
Using index
,这是覆盖索引生效的明确信号

唯一索引和普通索引选哪个

唯一索引(

UNIQUE
)在写入时多一次重复值校验,但对读性能几乎无影响;普通索引允许重复,写入略快。真正关键区别在于语义和锁行为:唯一索引在
INSERT ... ON DUPLICATE KEY UPDATE
REPLACE INTO
场景下能精准定位冲突行,减少锁范围。

实操建议:

业务上要求唯一性的字段(如
email
order_no
)必须建
UNIQUE
,既是约束也是性能保障
主键默认是聚簇唯一索引,不要额外建
UNIQUE(id)
如果只是想加速查询,且字段天然不唯一(如
status
),用普通索引即可,别强行加
UNIQUE

索引优化最易被忽略的点:不是“有没有索引”,而是“查询是否真的走到了它”。很多慢查根源不在 SQL 写法,而在统计信息过期、索引碎片、或缓冲池未预热——这些不会报错,但会让执行计划严重偏离预期。

相关推荐