mysql如何优化IS NULL与IS NOT NULL索引_mysql空值处理

0次阅读

IS NULL 可能走索引,取决于字段是否允许 NULL、索引类型及版本;5.7+ 二级索引中 NULL 被视为最小值,WHERE col IS NULL 可能命中索引,但需 EXPLAIN 验证。

mysql 如何优化 IS NULL 与 IS NOT NULL 索引_mysql 空值处理

IS NULL 走不走索引?先看执行计划

MySQL 对 IS NULL 的索引支持取决于字段是否允许为 NULL、索引类型和版本。5.7+ 的二级索引(B+Tree)默认会把 NULL 当作最小值存进去,所以 WHERE col IS NULL 是可能走索引的——但前提是这个索引是“有效覆盖”的,不是被优化器判定为“全表扫描更便宜”。

实操建议:

  • EXPLAIN SELECT * FROM t WHERE col IS NULLkeyrows 字段,别猜
  • 如果 col 是主键或唯一索引的一部分,IS NULL 一定不走索引(因为主键 / 唯一索引不允许 NULL)
  • 复合索引里,IS NULL 只能用于最左前缀中“连续非 NULL 条件之后的第一列”,比如索引 (a, b, c)WHERE a = 1 AND b IS NULL 可能走,但 WHERE a IS NULL AND b = 1 基本不走

IS NOT NULL 为什么经常不走索引?

IS NOT NULL 在绝大多数情况下等价于“排除极少数 NULL 值”,如果该列 NULL 比例很低,优化器会直接放弃索引、走全表扫描——因为随机 IO 成本比顺序扫描高得多。

常见错误现象:

  • 明明建了 INDEX(col)WHERE col IS NOT NULL 却显示 key=NULL
  • 加了 FORCE INDEX 强制走索引,查询反而变慢

原因很简单:索引只加速“定位”,不加速“排除”。当你要扫出 99% 的行时,B+Tree 跳来跳去读页,不如直接顺序读数据页快。

替代思路:

  • 如果业务上 NULL 是异常值(比如只有几条),改用 WHERE col > 0 或具体范围条件,更容易命中索引
  • 对高频 IS NOT NULL 查询,考虑在写入时补默认值(如 0''),并加 NOT NULL 约束,让优化器更敢用索引

NULL 值导致索引失效的隐藏场景

不是所有“看起来用了索引”的查询都真受益。NULL 会在几个关键位置悄悄破坏索引效率:

  • ORDER BY col 中,如果 col 允许 NULL,MySQL 默认把 NULL 排在最前面;若你加了 ORDER BY col DESC,NULL 又跑到最后——这会导致无法复用索引排序,触发 Using filesort
  • GROUP BY col 时,所有 NULL 被视为同一组,但索引本身不保证 NULL 的物理连续性,分组过程仍可能回表或临时表
  • 联合索引中某列为 NULL,可能导致后续列的索引值无法被下推,比如 INDEX(a, b)WHERE a IS NULL AND b = 5 通常不会用到 b 的索引部分

检查方法:在 EXPLAIN 输出里盯住 Extra 列,出现 Using filesortUsing temporary 就要警惕 NULL 是否搅局。

建表阶段怎么防 NULL 带来的索引麻烦?

与其后期调优,不如从源头控制 NULL 的出现。这不是教条主义,而是 MySQL 索引机制决定的现实约束。

实操建议:

  • 除明确需要表示“未知 / 缺失”的字段(如 end_time),其他一律加 NOT NULL + 合理默认值(如 created_at DEFAULT CURRENT_TIMESTAMP
  • 字符串字段慎用 DEFAULT NULL,宁可用 DEFAULT '';数值字段宁可用 DEFAULT 0,除非 0 本身有业务含义
  • 已有表想改,别直接 ALTER TABLE …… MODIFY col INT NOT NULL——会锁表。先 UPDATE 补 NULL 值,再 ALTER 加约束,分步做

真正难处理的,永远是那些“历史遗留的、NULL 含义模糊、又不敢随便改默认值”的字段。它们不会报错,但会让每个 IS NULL 都像在走钢丝。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-14发表,共计1493字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources