现在通过实例来验证下:
我的myslq版本是:8.0.19
建表语句
CREATE TABLE test_index (
id bigint(20) NOT NULL AUTO_INCREMENT,
a bigint(255) DEFAULT NULL,
b bigint(255) DEFAULT NULL,
c bigint(255) DEFAULT NULL,
PRIMARY KEY (id),
KEY index_b (b) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
其中b建了单独的索引
共插入10条数据:
一、IS NULL
依次减少该表b字段值为null的数量,分别执行以下sql看其执行计划:
EXPLAIN SELECT * FROM test_index WHERE b IS NULL;(= "")
结果:
当b字段为null的数量等于8的时候,会走索引
当b字段为null的数量为等于9个的时候,不会走索引
二、IS NOT NULL
依次增加该表b字段值不为null的数量,分别执行以下sql看其执行计划:
EXPLAIN SELECT * FROM test_index WHERE b IS NOT NULL;()
结果:
当b字段不为null的数量等于8时候,会走索引
当b字段不为null的数量等于9的时候,不会走索引
三、查询条件为= NULL 或者 != NULL
EXPLAIN SELECT * FROM t_union_index WHERE b = NULL;
EXPLAIN SELECT * FROM t_union_index WHERE b != NULL;
结果:不会走索引。
为什么会出现这种情况呢?
null 表示什么也不是, 不能=、>、< … 所有的判断,结果都是false,所有只能用 is null进行判断。
结论:
默认为Null的列,存在Null值会导致mysql优化器处理起来比较复杂,但是到底走不走索引,或者走那个索引,是要靠mysql优化器预先预估走那个索引成本比较低来决定的
我实验中的大致结果是:
查询条件中IS NULL,当命中结果数量小于等于80%的时候,会走索引(数据量越大比例会变动)。
查询条件中的IS NOT NULL,命中结果数量小于等于80%的时候,会走索引(数据量越大比例会变动)。