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三值逻辑与NULL
May 19 MySQL
MySQL 存储过程的优缺点分析
May 20 MySQL
MySQL中in和exists区别详解
Jun 03 MySQL
MySQL中存储时间的最佳实践指南
Jul 01 MySQL
Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写
Aug 02 MySQL
MYSQL 运算符总结
Nov 11 MySQL
解决Mysql多行子查询的使用及空值问题
Jan 22 MySQL
weblogic服务建立数据源连接测试更新mysql驱动包的问题及解决方法
Jan 22 MySQL
MySQL去除密码登录告警的方法
Apr 20 MySQL
mysql 体系结构和存储引擎介绍
May 06 MySQL
单机多实例部署 MySQL8.0.20
May 15 MySQL
MySQL分布式恢复进阶
Jul 23 MySQL
MYSQL如何查看操作日志详解
sql查询语句之平均分、最高最低分及排序语句
May 30 #MySQL
mysql5.5中文乱码问题解决的有用方法
深入理解MySQL中MVCC与BufferPool缓存机制
MYSQL事务的隔离级别与MVCC
详解Mysql数据库平滑扩容解决高并发和大数据量问题
MySQL中EXPLAIN语句及用法
May 20 #MySQL
You might like
利用php绘制饼状图的实现代码
2013/06/07 PHP
PHP检测接口Traversable用法详解
2017/12/29 PHP
用JavaScript对JSON进行模式匹配(Part 1-设计)
2010/07/17 Javascript
Javascript 自适应高度的Tab选项卡
2011/04/05 Javascript
js实现浏览器窗口大小被改变时触发事件的方法
2015/02/02 Javascript
jQuery EasyUI实现右键菜单变灰不可用效果
2015/09/24 Javascript
JavaScript中的继承之类继承
2016/05/01 Javascript
javascript中的后退和刷新实现方法
2016/11/10 Javascript
从源码看angular/material2 中 dialog模块的实现方法
2017/10/18 Javascript
详解Angular Forms中自定义ngModel绑定值的方式
2018/12/10 Javascript
vue中keep-alive组件的入门使用教程
2019/06/06 Javascript
layui使用form表单实现post请求页面跳转的方法
2019/09/14 Javascript
ES10的13个新特性示例(小结)
2019/09/23 Javascript
JavaScript闭包相关知识解析
2019/10/19 Javascript
小程序实现上传视频功能
2020/08/18 Javascript
原生JS实现拖拽功能
2020/12/16 Javascript
python获取指定时间差的时间实例详解
2017/04/11 Python
Python实现将数据框数据写入mongodb及mysql数据库的方法
2018/04/02 Python
python常用库之NumPy和sklearn入门
2019/07/11 Python
Python图像处理之图片文字识别功能(OCR)
2019/07/30 Python
基于Python 中函数的 收集参数 机制
2019/12/21 Python
Python代码注释规范代码实例解析
2020/08/14 Python
Python中实现一行拆多行和多行并一行的示例代码
2020/09/06 Python
基于python实现百度语音识别和图灵对话
2020/11/02 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
一款利用纯css3实现的超炫3D表单的实例教程
2014/12/01 HTML / CSS
html5桌面通知(Web Notifications)实例解析
2014/07/07 HTML / CSS
详解三种方式实现平滑滚动页面到顶部的功能
2019/04/23 HTML / CSS
领导检查欢迎词
2014/01/14 职场文书
秋季运动会活动方案
2014/02/05 职场文书
护士毕业生自荐信
2014/02/07 职场文书
党支部对照检查材料
2014/08/25 职场文书
美术教师个人工作总结
2015/02/06 职场文书
大学生心理健康教育心得体会
2016/01/12 职场文书
感恩信:写给爸爸妈妈的一封感谢信
2019/09/12 职场文书
Go语言使用select{}阻塞main函数介绍
2021/04/25 Golang