【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南

1. 核心查询与理想索引

  • 目标 SQLSELECT ... FROM 表 WHERE 字段0 = 0 AND fail IS NULL;
  • 理想索引方案 :建立联合索引 (字段0, fail) 。因为在 MySQL 索引中,IS NULL 被视作一个特定的等值,联合索引可以完美匹配这两个查询条件。

2. 实际操作中遇到的障碍(报错 1167)

  • 报错信息1167 - The used storage engine can't index column 'fail'
  • 根本原因fail 字段的数据类型是 TEXT 。MySQL 不允许对 TEXTBLOB 类型的字段创建完整索引,必须指定索引前缀长度

3. 两种解决方案对比

方案 具体操作 优点 缺点 / 注意事项
方案一(强烈推荐) 修改 fail 字段类型为 TINYINTINT (业务上通常表示布尔状态或计数),然后正常创建联合索引 (字段0, fail) 性能最佳 :索引体积小、查询极快;符合数据库设计规范,避免滥用 TEXT 修改大表字段类型会锁表,需在业务低峰期执行。
方案二(兜底方案) 保留 TEXT 类型,创建前缀索引(字段0, fail(100)) 无需改动表结构,能快速解决报错。 索引体积大、性能不如方案一;无法实现"覆盖索引"(需回表)。注意前缀长度需小于 767 字节(如 utf8mb4 下建议不超过 191)。

4. 最终结论与建议

  • 如果业务允许,请务必采用方案一 (改字段类型)。用 TEXT 存状态值属于设计失误,改掉它才是治本之策,后续所有相关查询都能受益。
  • 如果因特殊原因无法改表,采用方案二(前缀索引)作为临时或兜底措施,需接受其性能折损。
  • 操作完成后,务必用 EXPLAIN 验证,确保执行计划的 key 列显示为新索引,且 typerefrange
相关推荐
窝子面2 小时前
手搓最简前后端协作-node
javascript·数据库
吳所畏惧2 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
DFT计算杂谈2 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
HPFBoy2 小时前
log4net 数据库存日志正确配置
数据库
liuxiaowei32 小时前
【绝版教程】新版MySQL DBA高级实战进阶班 MySQL8.0 姜承尧-腾讯数据库总监
数据库·mysql·dba
破碎的南瓜3 小时前
sqli--sql注入过关笔记(1,2,3,4,5,9)
数据库·笔记·sql
吠品4 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
SelectDB5 小时前
Apache Doris Variant 动态 JSON 实战教程:从建表到跑通 100M Agent 日志查询
数据库
sg_knight5 小时前
MySQL 存储过程详解:从入门到实战
android·数据库·mysql·database·dba·关系型数据库·db