mysql字段为NULL索引是否会失效实例详解


Posted in MySQL onMay 30, 2022

项目场景:

很多博客说mysql在字段中创建普通索引,如果该索引中的数据存在null值是不走索引这个结论是错误的,不过尽量还是设置默认值。(版本8.0低于这个版本可能结果不一致)

1、创建表sc_base_color,其中普通索引为 “name,group_num”,这里暂时不测组合索引,下面再测试。

CREATE TABLE `sc_base_color` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `group_num` bigint DEFAULT NULL COMMENT '颜色代码',
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '颜色名称',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_name` (`name`),
  KEY `idx_group_num` (`group_num`)
) ENGINE=InnoDB AUTO_INCREMENT=574 DEFAULT CHARSET=utf8mb3 COMMENT='颜色';

2、初始化测试数据

INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (30, 1, '米黄');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (31, 1, '黑色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (32, 1, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (33, 1, '白色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (34, 1, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (35, 1, '绿色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (36, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (37, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (38, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (39, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (40, NULL, '紫色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (41, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (42, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (43, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (44, NULL, '蓝色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (45, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (46, NULL, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (47, 2, '米蓝色');
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (48, 2, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (49, 2, NULL);
INSERT INTO `sc_base_color`(`id`, `group_num`, `name`) VALUES (50, 2, '黑红色');

3、测试普通索引为NULL的情况是否使用了索引

使用 = 查询,测试结果中使用到了索引,其中索引字段的值为“NULL”

EXPLAIN select * from sc_base_color where name = '米黄';
EXPLAIN select * from sc_base_color where group_num = 1;

截图结果,两列数据都存在空,最终走了索引。

mysql字段为NULL索引是否会失效实例详解

使用 大于、小于 查询

EXPLAIN select * from sc_base_color where name > '米黄';
EXPLAIN select * from sc_base_color where name < '米黄';

截图结果

mysql字段为NULL索引是否会失效实例详解

使用 不等于、not in 、isnull、!isnull查询

EXPLAIN select * from sc_base_color where group_num != 1;
EXPLAIN select * from sc_base_color where group_num not in (1);
EXPLAIN select * from sc_base_color where  isnull(group_num);
EXPLAIN select * from sc_base_color where  !isnull(group_num);

截图结果

mysql字段为NULL索引是否会失效实例详解

使用isnull、is not null查询

# 使用is not null可能会导致索引失效,我测试了20条数据,只要null值占全部数据的百分之50就不会失效,否则会失效。又测了40条数据,23条数据不会为空,22条为null的会为空
EXPLAIN select  * from sc_base_color where  group_num is not null;
# 使用is null也可能会导致索引失效,我测试了20条数据,6数数据不为空不会失效,也就是可能当空的数据占比70%的时候索引会失效。
EXPLAIN select  * from sc_base_color where  group_num is  null;

由此可以得出结论,字段为空是可以走索引的,但是部分场景可能会失效,尽量还是给默认值。

4、测试组合索引为NULL是否走了索引

先删除普通索引字段,增加组合索引

ALTER TABLE sc_base_color DROP INDEX idx_group_num;
ALTER TABLE sc_base_color DROP INDEX idx_name;
alter table `sc_base_color` add index idx_group_num_idx_name (group_num, name);

测试 = > < 查询结果

EXPLAIN select  * from sc_base_color where  group_num > 1;
EXPLAIN select  * from sc_base_color where  group_num < 1;
EXPLAIN select  * from sc_base_color where  group_num = 1;
EXPLAIN select  * from sc_base_color where group_num = 1 and name = '米黄';

截图结果,是可以走索引的,下面的逻辑就不用测试了和普通索引一样,除非不符合最左匹配原则直接查询name字段。

mysql字段为NULL索引是否会失效实例详解

5、总结

在设计数据库的时候尽量还是给字段的默认值。

1、比如int、bigint类型默认值为-1/0

2、比如varchar类型默认值为空串

3、bigdecimal类型为0等等。

NULL值会有不少坑

1、count(字段NULL)会过滤统计的数据,sum这些函数也会

2、使用> < 的时候也会过滤掉为NULL的数据

3、group by 的时候会把所有为NULL的数据合并,可以随机生成UUID解决

4、还有场景可能也有问题,这里我也忘记了,用的时候才会想起来。

总结

到此这篇关于mysql字段为NULL索引是否会失效的文章就介绍到这了!


Tags in this post...

MySQL 相关文章推荐
MySQL如何构建数据表索引
May 13 MySQL
MySQL 覆盖索引的优点
May 19 MySQL
MySQL完整性约束的定义与实例教程
May 30 MySQL
MYSQL 无法识别中文的永久解决方法
Jun 03 MySQL
Mysql systemctl start mysqld报错的问题解决
Jun 03 MySQL
Mysql 如何实现多张无关联表查询数据并分页
Jun 05 MySQL
Mysql外键约束的创建与删除的使用
Mar 03 MySQL
MySQL中一条update语句是如何执行的
Mar 16 MySQL
数据分析数据库ClickHouse在大数据领域应用实践
Apr 03 MySQL
排查并解决MySQL生产库内存使用率高的报警
Apr 11 MySQL
MySQL创建管理HASH分区
Apr 13 MySQL
MySQL串行化隔离级别(间隙锁实现)
Jun 16 MySQL
MYSQL如何查看操作日志详解
sql查询语句之平均分、最高最低分及排序语句
May 30 #MySQL
mysql5.5中文乱码问题解决的有用方法
深入理解MySQL中MVCC与BufferPool缓存机制
MYSQL事务的隔离级别与MVCC
详解Mysql数据库平滑扩容解决高并发和大数据量问题
MySQL中EXPLAIN语句及用法
May 20 #MySQL
You might like
php引用传值实例详解学习
2013/11/06 PHP
PHP实现QQ空间自动回复说说的方法
2015/12/02 PHP
PHP开发的微信现金红包功能示例
2017/06/29 PHP
Javascript &amp; DHTML 实例编程(教程)基础知识
2007/06/02 Javascript
jquery弹出框的用法示例(2)
2013/08/26 Javascript
模拟jQuery中的ready方法及实现按需加载css,js实例代码
2013/09/27 Javascript
JavaScript实现简单的时钟实例代码
2013/11/23 Javascript
JavaScript实现的简单幂函数实例
2015/04/17 Javascript
浅谈javascript中return语句
2015/07/15 Javascript
详解JavaScript语言的基本语法要求
2015/11/20 Javascript
JavaScript必知必会(二) null 和undefined
2016/06/08 Javascript
AngularJS通过$sce输出html的方法
2016/09/22 Javascript
在React 组件中使用Echarts的示例代码
2017/11/08 Javascript
vue interceptor 使用教程实例详解
2018/09/13 Javascript
vue中组件的过渡动画及实现代码
2018/11/21 Javascript
Vue唯一可以更改vuex实例中state数据状态的属性对象Mutation的讲解
2019/01/18 Javascript
为什么要使用Vuex的介绍
2019/01/19 Javascript
详解关于webpack多入口热加载很慢的原因
2019/04/24 Javascript
vue实现数字滚动效果
2020/06/29 Javascript
python学习笔记:字典的使用示例详解
2014/06/13 Python
python类装饰器用法实例
2015/06/04 Python
初学python的操作难点总结(新手必看篇)
2017/08/03 Python
PyCharm在win10的64位系统安装实例
2017/11/26 Python
为什么说Python可以实现所有的算法
2019/10/04 Python
pytorch实现MNIST手写体识别
2020/02/14 Python
Python unittest工作原理和使用过程解析
2020/02/24 Python
HTML5 和小程序实现拍照图片旋转、压缩和上传功能
2018/10/08 HTML / CSS
实习生单位鉴定意见
2013/12/04 职场文书
师范学院美术系毕业生自我鉴定
2014/01/29 职场文书
2014年端午节活动方案
2014/03/11 职场文书
九寨沟导游词
2015/02/02 职场文书
2015年财政局工作总结
2015/05/21 职场文书
感恩主题班会教案
2015/08/12 职场文书
电力安全学习心得体会
2016/01/18 职场文书
Java spring定时任务详解
2021/10/05 Java/Android
游戏《铁拳》动画化!2022年年内播出
2022/03/21 日漫