不适合------重复值多的列不宜单独建普通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助手,依托大模型,帮助用户记录、整理和分析音视频内容,体验用大模型做音视频笔记、整理会议记录。
相关推荐
这个DBA有点耶1 小时前
GROUP BY优化全解:如何写出既不丢数据又飞快的分组查询掉头发的王富贵4 小时前
【StarRocks】极限十分钟入门StarRocksNturmoils4 小时前
WHERE 条件别凭习惯写,常用查询先跑一遍荣码8 小时前
LangGraph多Agent协作:3个Agent干活比1个强,但我踩了4个坑用户8356290780511 天前
Python 操作 PDF 附件:添加、查看与管理指南Databend1 天前
在 AWS 中国峰会逛了一天,我在 Databend 展台看到了 Agent 数据基础设施的新思路宇宙之一粟1 天前
乐企版式文件生成平台学测绘的小杨2 天前
CompassFusion:一个从 GNSS 到 GNSS/INS 组合导航的独立工程包ClouGence2 天前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因zzzzzz3102 天前
当产品经理说这个很简单:我用Python自动化处理奇葩需求的实战指南