为什么SQL查询即使单索引下也慢,关联字段选择性低是关键因素吗?
- 内容介绍
- 相关推荐
本文共计1035个文字,预计阅读时间需要5分钟。
关联查询走索引可能比较慢,常见原因是关联字段分区度过低——例如使用status(只有0/1/2三个值)或gender(男/女)做ON条件。MySQL虽然可能走索引,但type可能是ref或range,实际需要扫描几万行才能得到结果,和全表扫描没有本质区别。
选择性 = 唯一值数量 / 总行数。低于 0.01(即 1%)就属于低选择性。这种字段单独建索引意义不大,优化器很可能直接放弃使用。
- 用
SELECT COUNT(DISTINCT status) / COUNT(*) FROM orders;快速估算 - 如果结果是
0.003,说明每 300 行才有一个新值,索引基本等于摆设 - 别急着加索引,先确认这个字段是不是真该出现在
ON或WHERE里——有时是业务逻辑写错了,把过滤条件误当关联条件
EXPLAIN里rows远大于预期?说明索引没拦住多少数据
EXPLAIN输出里的rows列,代表 MySQL 预估需要扫描的行数。如果关联后rows高达几十万,哪怕type显示ref,也说明索引只缩小了范围,没真正“切掉”大部分数据。
本文共计1035个文字,预计阅读时间需要5分钟。
关联查询走索引可能比较慢,常见原因是关联字段分区度过低——例如使用status(只有0/1/2三个值)或gender(男/女)做ON条件。MySQL虽然可能走索引,但type可能是ref或range,实际需要扫描几万行才能得到结果,和全表扫描没有本质区别。
选择性 = 唯一值数量 / 总行数。低于 0.01(即 1%)就属于低选择性。这种字段单独建索引意义不大,优化器很可能直接放弃使用。
- 用
SELECT COUNT(DISTINCT status) / COUNT(*) FROM orders;快速估算 - 如果结果是
0.003,说明每 300 行才有一个新值,索引基本等于摆设 - 别急着加索引,先确认这个字段是不是真该出现在
ON或WHERE里——有时是业务逻辑写错了,把过滤条件误当关联条件
EXPLAIN里rows远大于预期?说明索引没拦住多少数据
EXPLAIN输出里的rows列,代表 MySQL 预估需要扫描的行数。如果关联后rows高达几十万,哪怕type显示ref,也说明索引只缩小了范围,没真正“切掉”大部分数据。

