避免全表扫描的关键是合理使用索引:为高频查询和连接字段建索引,遵循最左前缀原则,且不在索引列上使用函数或表达式。

避免全表扫描是 MySQL 查询优化的关键一步,核心在于让查询能有效利用索引,减少不必要的数据读取。
确保查询条件字段有合适索引
全表扫描往往是因为 WHERE、JOIN、ORDER BY 或 GROUP BY 中使用的字段缺少索引。不是所有字段都适合建索引,重点覆盖高频查询条件和连接字段。
- 对 WHERE 子句中频繁出现的列(如user_id、status、create_time)建立单列或联合索引
- 联合索引注意最左前缀原则:查询包含索引最左侧连续列时才能命中,例如索引 (a, b, c),可命中a、a,b、a,b,c,但无法命中b 或b,c
- 避免在索引列上使用函数或表达式,如 WHERE YEAR(create_time) = 2024 会跳过索引,应改写为WHERE create_time >= ‘2024-01-01’ AND create_time
检查执行计划,确认是否走索引
用 EXPLAIN 分析 SQL,重点关注 type、key、rows 和Extra字段。
- type值为 ALL 表示全表扫描;理想是 const、ref、range 或index
- key显示实际使用的索引名,为空说明未走索引
- rows越小越好,代表预估扫描行数;若远大于结果集数量,说明索引选择不佳或存在隐式类型转换
- Extra中出现 Using filesort 或Using temporary虽不等于全表扫描,但常伴随性能问题,需结合索引优化
避免导致索引失效的常见写法
即使有索引,某些 SQL 写法也会让优化器放弃使用它。
- 使用 != 或(非等值判断通常无法高效利用 B + 树索引)
- 对索引列使用 LIKE 且以通配符开头,如 name LIKE ‘%abc’;可改为name LIKE ‘abc%’ 并配合前缀索引
- 索引列参与运算或类型隐式转换,如WHERE mobile = 13812345678(mobile 是 VARCHAR),MySQL 会将整数转为字符串比对,可能使索引失效
- OR 连接多个条件时,只有所有分支字段都有索引才可能走索引;否则建议拆成 UNION 或改用 IN
合理设计索引,不过度依赖单列索引
单列索引堆砌容易引发索引冗余,而联合索引设计不当又会导致覆盖不足。
- 优先考虑高频组合查询场景,把过滤性最强的列放在联合索引最左侧
- 利用覆盖索引减少回表:SELECT 只查索引列时,可直接从索引获取全部数据,避免访问聚簇索引(主键索引)
- 对大文本或长字符串字段,考虑前缀索引(如INDEX idx_title (title(50))),平衡索引大小与区分度
- 定期用 SHOW INDEX FROM table_name 和慢查询日志分析索引使用率,删除长期未被命中的冗余索引






























