現(xiàn)在通過(guò)實(shí)例來(lái)驗(yàn)證下:
我的myslq版本是:8.0.19
建表語(yǔ)句
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建了單獨(dú)的索引
共插入10條數(shù)據(jù):

一、IS NULL
依次減少該表b字段值為null的數(shù)量,分別執(zhí)行以下sql看其執(zhí)行計(jì)劃:
EXPLAIN SELECT * FROM test_index WHERE b IS NULL;(= "")
結(jié)果:
當(dāng)b字段為null的數(shù)量等于8的時(shí)候,會(huì)走索引

當(dāng)b字段為null的數(shù)量為等于9個(gè)的時(shí)候,不會(huì)走索引

二、IS NOT NULL
依次增加該表b字段值不為null的數(shù)量,分別執(zhí)行以下sql看其執(zhí)行計(jì)劃:
EXPLAIN SELECT * FROM test_index WHERE b IS NOT NULL;()
結(jié)果:
當(dāng)b字段不為null的數(shù)量等于8時(shí)候,會(huì)走索引

當(dāng)b字段不為null的數(shù)量等于9的時(shí)候,不會(huì)走索引

三、查詢條件為= NULL 或者? != NULL
EXPLAIN SELECT * FROM t_union_index WHERE b = NULL;
EXPLAIN SELECT * FROM t_union_index WHERE b != NULL;
結(jié)果:不會(huì)走索引。
為什么會(huì)出現(xiàn)這種情況呢?
null 表示什么也不是, 不能=、>、< … 所有的判斷,結(jié)果都是false,所有只能用 is null進(jìn)行判斷。
結(jié)論:
默認(rèn)為Null的列,存在Null值會(huì)導(dǎo)致mysql優(yōu)化器處理起來(lái)比較復(fù)雜,但是到底走不走索引,或者走那個(gè)索引,是要靠mysql優(yōu)化器預(yù)先預(yù)估走那個(gè)索引成本比較低來(lái)決定的
我實(shí)驗(yàn)中的大致結(jié)果是:
查詢條件中IS NULL,當(dāng)命中結(jié)果數(shù)量小于等于80%的時(shí)候,會(huì)走索引(數(shù)據(jù)量越大比例會(huì)變動(dòng))。
查詢條件中的IS NOT NULL,命中結(jié)果數(shù)量小于等于80%的時(shí)候,會(huì)走索引(數(shù)據(jù)量越大比例會(huì)變動(dòng))。