不适合------重复值多的列不宜单独建普通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助手,依托大模型,帮助用户记录、整理和分析音视频内容,体验用大模型做音视频笔记、整理会议记录。
相关推荐
环流_1 小时前
Redis中set类型以及应用场景kexnjdcncnxjs1 小时前
SQL批量删除不同条件的记录_使用IN子句简化删除逻辑liux35281 小时前
Kafka 4.1.1 生产环境调优与最佳实践指南2303_821287381 小时前
如何安装Oracle 12c Cloud Control_OMS服务端组件与Agent部署Be reborn1 小时前
用例不是孤立执行的:依赖、变量池与 storage_state 设计m0_609160491 小时前
React Flow 边缘错位与消失问题的根源分析与 Hooks 重构方案Marvel__Dead1 小时前
微调 Gemma 4 识别腾讯天御全系列验证码【解决方案-一个模型识别 滑块|文字点选|图标点选|空间点选】weixin_444012931 小时前
CSS怎样调整弹性项目排列顺序_使用order属性轻松控制DOM显示顺序l1t1 小时前
DeepSeek总结的PostgreSQL 18.4, 17.10, 16.14, 15.18 和 14.23 发布