谣言止于“实验”——MYSQL NULL 与索引

时间:2022-06-26
本文章向大家介绍谣言止于“实验”——MYSQL NULL 与索引,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

如果经常混坛子,你会听说一种言论,就是NULL 走不了索引,尤其在MYSQL的论坛里面,基本上不出意外,你每天都能看到这样的言论。事实上是怎样,或许没人关注,而到底 NULL 走不走索引,其实是有必要进行一番验证的。本次使用了 MYSQL 8.015 来做这个验证。

首先的先标准化一些事情

1 数据表到底是哪种格式 (DYNAMIC)

2 此种格式的特点,以及NULL 在这样存储格式是怎么进行处理的

Dynamic 这种行的存储格式有一些特点

1 所有的字符串的值大于 4 的都是动态的

2 每一行前都有一个位图,位图指示哪些列包含空字符串或零。如果字符串列在删除尾随空间后长度为零,或者数字列的值为零,则在位图中标记它,而不是保存到磁盘。非空字符串保存为长度字节加上字符串内容。

3 空列需要行中额外的空间来记录它们的值是否为空。

从上面的话,总结出来一句话,NULL 需要额外的空间来保存他,对比在你的字段里面'' 或者 0 来表明默认值,NULL 比他们更浪费空间。

在MYSQL5.7中NULL 是可以用N 来代表NULL ,但在MYSQL 8 中被废弃了,NULL 就是NULL 来代表。

这里有一个问题,提出NULL 不好,而要表设计中尽量不为空的依据是哪里来的。我们可以根据官方文档中的一段话来说明。

其中有几句,不使用NULL,可以

1 更好的使用INDEX

2 节省空间

3 加速SQL 的运行

OK,那我们就来做一下实验,看看怎么来证明使用NULL 到底能不能走索引

从上图来看,查询空值是可以走索引的。那我们换只用写法我们差 is not null

看上去的确是is not null是不能走索引,但实际上是这样的吗,是数量引起的全表扫描,还是is not null引起的问题?

下面的实验证明 is not null也是可以走索引的,而is not null 无法走索引的情况和平时其他走不了索引的情况是一样的,主要还是看cost 成本计算。

如果是OR 条件中 使用 is null or is null ,从下图看是可以走索引的

按照索引的原理,二级索引的值是可以为NULL, 而索引的列值为NULL 的二级索引记录来说,B+树种的NULL 的值存在哪里,一般来说是B+树的最左边。

我们继续进行测试,如果将部分条件和 is not null联合进行查询,从下图看也是会走相关索引的。

所以上面的实验证明了, is null , is not null 都是可以走相关的索引的,如果不走索引要不就是相关走INDEX 的成本比全表扫描还高,要不就是索引可能失效,或统计分析出了问题。