贝利信息

mysql中使用索引优化WHERE子句的查询性能

日期:2026-01-22 00:00 / 作者:P粉602998670
WHERE字段无索引会导致全表扫描;EXPLAIN中key为NULL且rows接近总行数即证实;需注意联合索引最左前缀、函数/隐式转换致失效、LIKE前缀匹配才走索引、ORDER BY需纳入索引避免filesort。

WHERE条件字段没加索引,查询会全表扫描

MySQL在执行 WHERE 查询时,如果过滤字段上没有索引,优化器通常会选择全表扫描(type: ALL),数据量稍大就明显变慢。用 EXPLAIN 查看执行计划是最直接的判断方式:

EXPLAIN SELECT * FROM orders WHERE user_id = 123;

若结果中 key 列为 NULL,说明没走索引;rows 值接近表总行数,基本就是全扫了。

常见疏忽点:

联合索引的最左前缀原则必须严格遵守

MySQL联合索引(如 INDEX idx_status_time (status, created_at))只支持从左到右匹配。以下查询能命中索引:

WHERE status = 'shipped'
WHERE status = 'shipped' AND created_at > '2025-01-01'

但这些不行:

WHERE created_at > '2025-01-01'  -- 缺少 status,跳过最左列
WHERE status IN ('paid','shipped') AND created_at > '2025-01-01'  -- IN 后范围查询,created_at 可能无法继续使用索引

注意点:

LIKE 模糊查询只有前缀匹配才走索引

LIKE 是否能用索引,关键看通配符位置:

如果业务必须做前后模糊搜索,不要硬扛索引,考虑:

ORDER BY 和 LIMIT 配合索引能避免 filesort

WHERE 已用索引,但 ORDER BY 字段不在该索引中,MySQL 会额外触发 Using filesort,性能损耗显著。例如:

SELECT * FROM products WHERE category_id = 5 ORDER BY price DESC LIMIT 10;

若只有 INDEX(category_id),就会 filesort;加上联合索引 INDE

X(category_id, price) 就可直接按索引顺序取前 10 条。

注意事项:

索引不是越多越好,每增一个索引都会拖慢写入,并占用磁盘和内存。真正关键的是理解查询模式、看清 EXPLAIN 输出、验证索引是否真的被用上——很多时候加了索引却因类型不匹配或写法不当而白费。