不适合------重复值多的列不宜单独建普通B+树索引,因其低基数导致空间浪费、写入变慢、优化器弃用;应优先作为组合索引后缀,或改用前缀索引、函数索引(MySQL 8.0.13+)等替代方案。重复值多的列适合建索引吗?不适合------至少不能只建普通 B+ 树索引。MySQL 的 INDEX 在高重复率列上会严重浪费空间、拖慢写入,且查询优化器大概率不走这个索引。原因很简单:B+ 树靠有序性加速查找,但像 status(只有 'active'/'inactive')、gender 这类低基数列,索引页里大量指针指向几乎同一组数据,导致树高没优势、范围扫描仍要回表大量行,优化器直接判定"全表扫更快"。常见错误现象:EXPLAIN 显示 type=ALL 或 key=NULL,哪怕你明明建了索引使用场景:这类字段常出现在 WHERE 条件末尾(如 WHERE user_id = ? AND status = ?),应优先考虑组合索引中作为后缀列参数差异:InnoDB 对重复值不做压缩,每个重复键都存完整记录 + 主键引用,100 万行、90% 是 'active',索引就存约 90 万条几乎一样的 status 条目唯一性差的列怎么建索引才有效?要么塞进组合索引做后缀,要么改用前缀索引或函数索引(MySQL 8.0.13+)。组合索引是首选方案:把高区分度列放前面,低区分度列放后面。例如 (user_id, status) 能高效支持 WHERE user_id = 123 AND status = 'active',甚至 WHERE user_id = 123;但反过来 (status, user_id) 就基本失效。性能影响:前缀列区分度越低,组合索引的"剪枝"能力越弱;(status, created_at) 在时间范围查询中可能比单列 created_at 索引还慢兼容性注意:MySQL 5.7 不支持函数索引,JSON_EXTRACT() 或 LOWER() 等表达式无法直接建索引,得靠生成列 + 索引模拟实操建议:用 SELECT COUNT(DISTINCT status) / COUNT(*) FROM table; 算出选择率,低于 0.01(1%)就别单独建索引为什么加了索引还是慢?检查这三处不是所有"有索引"都等于"能用上"。尤其在重复值多的场景下,最容易卡在这三个环节: 通义听悟 阿里云通义听悟是聚焦音视频内容的工作学习AI助手,依托大模型,帮助用户记录、整理和分析音视频内容,体验用大模型做音视频笔记、整理会议记录。
相关推荐
Dicky-_-zhang6 小时前
分布式系统限流熔断实战:保护微服务稳定性IpdataCloud6 小时前
如何用Python和IP离线库查询IP归属地?获取国家、城市、经纬度的完整代码jran-6 小时前
MySQL 用户与权限EnCi Zheng6 小时前
09-斯坦福CS336作业 [特殊字符]端平入洛6 小时前
Python 切片赋值 vs 普通赋值:你真的改了那个 list 吗?無限進步D6 小时前
MySQL 排序与分页大G的笔记本6 小时前
Redis 分布式锁自动续期机制Solis程序员6 小时前
跳出 CRUD:深入剖析 Redis 管道 Pipeline 底层通信机制smj2302_796826527 小时前
解决leetcode第3934题最短唯一子数组