mysql如何选择正确的索引字段_mysql高基数与低基数选择

0次阅读

WHERE 条件未走索引主因是字段基数低,如 status 仅 3 个值,选择率超 20% 时优化器认为全表扫描更优;复合索引应按等值过滤→范围查询→排序顺序排列;前缀索引需验证选择率 >95%;key_len 偏小表明索引断裂。

mysql 如何选择正确的索引字段_mysql 高基数与低基数选择

为什么 WHERE 条件里用了字段却没走索引?

常见现象是:明明给 status 字段加了索引,SELECT * FROM orders WHERE status = 'paid' 却还是全表扫描。根本原因不是索引没建,而是该字段基数太低——比如只有 'pending''paid''cancelled' 三种值,重复率极高。

MySQL 的优化器会估算:如果一个值占全表 20% 以上行数,走索引反而比全表扫描更慢(要回表、随机 IO 多)。所以它直接放弃索引。

  • 低基数字段(如 genderis_deletedstatus)单独建索引通常无效
  • 高基数字段(如 user_idorder_noemail)天然适合做索引主干
  • SELECT COUNT(DISTINCT col) / COUNT(*) FROM table 粗略算下选择率,低于 5% 才值得单独索引

ORDER BYWHERE 混用时,字段顺序怎么排?

复合索引的字段顺序不是按 SQL 里写的顺序来,而是按“过滤 → 排序 → 查询”优先级排列。比如 SELECT name FROM users WHERE city = ? AND age > ? ORDER BY created_at DESC,索引应该建为 (city, age, created_at),而不是 (city, created_at, age)

  • WHERE 中的等值条件(=IN)放最前,它们能快速定位数据块
  • 范围查询(><BETWEEN)只能放等值之后,且只能有一个(后续字段索引失效)
  • ORDER BY 字段必须紧接在可利用的 WHERE 字段之后,否则无法避免 Using filesort
  • 如果 ORDER BY 是多字段且含方向(如 ORDER BY a ASC, b DESC),MySQL 8.0+ 才支持混合方向索引;之前版本统一按 ASC 建,DESC 字段实际不走索引排序

什么时候该用前缀索引?VARCHAR(255) 不要直接全字段索引

对长文本字段(如 titleurl)建完整索引,不仅浪费空间,还会拖慢写入和缓冲池效率。但直接不索引又没法加速模糊查或等值查。

前缀索引是折中解法:只取前 N 个字符建索引。关键是选对 N —— 要让前缀足够“区分”,又别太长。

  • 先跑 SELECT COUNT(DISTINCT LEFT(url, 10)) / COUNT(*) FROM pages,看 10 位前缀的选择率是否 > 95%
  • 逐步增加长度(15、20……),直到选择率不再明显提升,就定这个长度
  • 注意:前缀索引不支持 ORDER BYGROUP BY 该字段,也不支持 LIKE '%xxx'(左模糊)
  • 如果业务真需要 LIKE '%xxx',别硬扛,换 全文索引 或外部搜索引擎

EXPLAIN 里看到 key_len 比预期小,说明什么?

key_len 显示 MySQL 实际用了索引的多少字节。比如你建了 (a, b, c) 索引,但 EXPLAIN SELECT …… WHERE a = ? AND c = ? 发现 key_len 只有 a 的长度,b 和 c 没用上——这说明索引断裂了。

  • 原因通常是跳过了中间字段:没有 b 的条件,c 就无法利用索引排序或查找
  • key_len 值偏小,往往对应 type: refrange,但实际扫描行数远超预期,得结合 rowsExtra(如 Using index condition)一起看
  • 对于 UTF8MB4 字段,key_len 计算要按最大字节数算(比如 VARCHAR(100) 最多占 400 字节),别拿字符数去比

基数判断和索引字段顺序不是靠经验猜的,是得对着 EXPLAIN 和真实数据分布反复验证的事。尤其当表大了以后,低基数字段混进复合索引,或者前缀长度拍脑袋定,很容易变成隐藏性能杀手。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-16发表,共计1563字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources