mysql索引优化对性能提升有多大_mysql索引使用技巧

7次阅读

索引提速效果取决于场景,高基数等值查询可百倍加速,低基数列索引常被忽略;复合索引需按最左前缀原则设计,选择性高的列优先;覆盖索引(using index)仍可能因索引宽、重复值多或结果集大而变慢;函数操作、隐式类型转换等会使索引失效。

mysql索引优化对性能提升有多大_mysql索引使用技巧

索引能提速多少?看场景,不是所有查询都受益

索引不是“一加就快”,它的收益高度依赖查询模式和数据分布。在理想情况下(如高基数字段上的等值查询),WHERE user_id = 12345 从全表扫描(O(n))降到 B+ 树查找(O(log n)),百万行表可能从 800ms 降到 5ms —— 提速百倍。但低基数列(如 status enum('active','inactive'),只有两个值)上建索引,优化器大概率直接忽略它,因为走索引还要回表,不如全表扫得干脆。mysql 通常在列唯一值占比低于约 30% 时放弃使用该索引。

复合索引怎么排顺序?最左前缀不是玄学

复合索引 INDEX idx_name_phone (name, phone) 能命中 WHERE name = 'Alice'WHERE name = 'Alice' AND phone = '138xxxx',但对 WHERE phone = '138xxxx' 完全无效——这就是“最左前缀原则”。顺序决定覆盖能力:

  • 把选择性高的列(如 user_id)放前面,比把低选择性列(如 gender)放前面更有效;
  • 如果常查 WHERE category = ? AND created_at > ? ORDER BY created_at DESC,那 (category, created_at)(created_at, category) 更合适,因为范围查询后的列无法用于索引排序;
  • 避免冗余:已有 (a, b, c),再建 (a, b) 就是浪费空间和写开销。

为什么 EXPLAIN 显示“Using index”却还是慢?

Using index 表示用了覆盖索引(Covering Index),即查询所需所有字段都在索引里,不用回表——这本该很快。但如果出现慢,常见原因有:

  • 索引本身太宽:比如在 VARCHAR(1000) 字段上建了前缀长度为 255 的索引,单个索引项变大,B+ 树层级加深,IO 次数上升;
  • 大量重复值导致索引页内扫描行数多(例如 WHERE status IN ('pending','processing') 匹配几十万行,即使覆盖索引也要遍历这么多索引记录);
  • 查询返回结果集过大,网络传输或客户端处理成了瓶颈,而非索引本身问题。

哪些操作会让索引彻底失效?

不是写了 WHERE 就能用索引。这些写法会让 MySQL 直接放弃走索引:

  • 对索引列用函数:WHERE YEAR(create_time) = 2025 → 改成 WHERE create_time >= '2025-01-01' AND create_time ;
  • 隐式类型转换WHERE mobile = 13812345678(mobile 是 VARCHAR)→ 数字会被转字符串,但部分版本不走索引,统一用引号写成 '13812345678'
  • LIKE 左模糊:WHERE name LIKE '%abc' 无法利用 B+ 树有序性;右模糊 'abc%' 可以;
  • OR 连接非索引列:WHERE indexed_col = 1 OR non_indexed_col = 2,整条条件大概率退化为全表扫描。

真正难的从来不是“建不建索引”,而是理解你的查询在引擎内部走了哪条路径——EXPLAIN 看懂了,90% 的索引问题就定位了一半。

text=ZqhQzanResources