【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
相关推荐
!chen41 分钟前
数据库主从有延迟怎么处理
数据库·adb
SelectDB技术团队43 分钟前
Apache Doris 多云原生实践:SaaS、BYOC 与四大公有云覆盖
数据库·阿里云·云原生·华为云·腾讯云·亚马逊云·写入更新
云飞云共享云桌面3 小时前
医疗器械设备研发:多人同时操作 SolidWorks,怎样依靠单台服务器替代多工作站
运维·服务器·网络·数据库·制造
知行合一。。。8 小时前
RAG--03--Milvus基本用法
数据库·oracle·milvus
TDengine (老段)8 小时前
TDengine 线程模型 — 网络、调度、执行
大数据·数据库·物联网·制造·时序数据库·tdengine·涛思数据
上学的小垃圾10 小时前
01-数据库系统概述
数据库
二进制漫游记10 小时前
FastAPI项目集成 Qdrant向量数据库+阿里云Embedding完整实战(工具封装+业务调用)
数据库·python·阿里云·embedding
2501_9289962210 小时前
GPT-4o换DeepSeek迁移成本多少?中科热备解析API聚合平台技术账本
前端·数据库·人工智能
泡干脆面就番茄12 小时前
MySQL_子查询_分页查询与联合查询详解
数据库·mysql
devpotato13 小时前
缓存与数据库更新顺序不一致问题
java·数据库·redis