mysql索引如何加速查询_mysql查询性能提升分析

13次阅读

索引加速 SELECT 查询的根本原因是改变数据访问方式:无索引需全表扫描,有合适索引可直接定位目标行或范围,依赖 B + 树有序结构和最左前缀匹配规则。

mysql 索引如何加速查询_mysql 查询性能提升分析

索引 为什么 能加速 SELECT 查询

根本原因不是“索引快”,而是它改变了 数据访问 方式:没有索引时,MySQL 必须全表扫描(type: ALL),逐行比对;有合适索引时,可直接定位到目标行或范围,跳过大量无关数据。这依赖 B+ 树的有序结构和最左前缀匹配规则。

注意:索引只在查询条件中实际用到的列上生效。比如建了 (a, b, c) 联合索引,但查询写的是 WHERE b = 1,该索引大概率不会被使用——因为不满足最左前缀。

  • EXPLAINkeypossible_keys 是否命中索引
  • type 字段是关键:const/ref/range 表示走了索引,ALLindex 往往意味着慢
  • 索引列参与计算(如 WHERE YEAR(create_time) = 2023)或加了函数 / 表达式,会导致索引失效

哪些字段适合建索引

不是“查得频繁就加索引”,而是看是否具备高选择性、是否出现在 WHERE / JOIN / ORDER BY / GROUP BY 子句中,并且未被函数包裹。

  • 主键自动建聚簇索引,无需额外操作
  • 外键字段建议建索引,避免关联查询时锁表或全表扫描
  • 经常用于排序的字段(如 ORDER BY created_at DESC),可考虑联合索引覆盖排序需求
  • 区分度低的字段(如 gender 只有男 / 女)单独建索引意义不大,但作为联合索引的后缀可能有效
  • 大文本字段(TEXTVARCHAR(2000))不能直接建完整索引,需指定前缀长度,如 INDEX idx_title (title(100))

ALTER TABLE …… ADD INDEX 的实际影响

在线加索引在 MySQL 5.6+ 支持 ALGORITHM=INPLACE,但仍会阻塞写操作(INSERT/UPDATE/DELETE),且占用磁盘空间翻倍(临时索引文件 + 原表)。生产环境务必避开高峰期执行。

  • 加索引前先用 SHOW CREATE TABLE 确认当前索引结构,避免重复创建
  • 联合索引顺序很重要:(status, user_id)(user_id, status) 是两个完全不同的索引,适用场景不同
  • 删除无用索引用 DROP INDEX idx_name ON table_name,减少写入开销和维护成本
  • 监控 information_schema.STATISTICS 或使用 sys.schema_unused_indexes(MySQL 8.0+)识别长期未命中的索引

为什么加了索引反而变慢

常见错觉:只要建了索引,查询一定快。实际上,优化器可能因统计信息过期、索引选择率误判或查询条件太宽泛而放弃使用索引,转为全表扫描。更隐蔽的问题是索引本身成了负担。

  • 小表(比如几千行)加索引收益极小,甚至因多一次 B + 树查找而更慢
  • 写多读少的表,每个 INSERT 都要更新多个索引,拖慢整体吞吐
  • LIKE '%abc' 这类前导通配符无法使用索引,但 LIKE 'abc%' 可以
  • 隐式类型转换 导致索引失效,例如字段是 VARCHAR,却用数字查询:WHERE mobile = 13800138000(应加引号)

真正有效的索引优化,永远从 EXPLAIN 结果出发,结合真实查询模式和数据分布来判断,而不是凭经验堆砌索引。

text=ZqhQzanResources