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 相关文章推荐
JDBC连接的六步实例代码(与mysql连接)
May 12 MySQL
正确使用MySQL INSERT INTO语句
May 26 MySQL
MySQL5.7并行复制原理及实现
Jun 03 MySQL
MySQL 不等于的三种使用及区别
Jun 03 MySQL
浅谈mysql增加索引不生效的几种情况
Jun 23 MySQL
一篇文章带你深入了解Mysql触发器
Aug 02 MySQL
MySQL配置主从服务器(一主多从)
Aug 07 MySQL
Mysql案例刨析事务隔离级别
Sep 25 MySQL
如何避免mysql启动时错误及sock文件作用分析
Jan 22 MySQL
深入讲解数据库中Decimal类型的使用以及实现方法
Feb 15 MySQL
MySQL的InnoDB存储引擎的数据页结构详解
Mar 03 MySQL
MySQL日期时间函数知识汇总
Mar 17 MySQL
MYSQL如何查看操作日志详解
sql查询语句之平均分、最高最低分及排序语句
May 30 #MySQL
mysql5.5中文乱码问题解决的有用方法
深入理解MySQL中MVCC与BufferPool缓存机制
MYSQL事务的隔离级别与MVCC
详解Mysql数据库平滑扩容解决高并发和大数据量问题
MySQL中EXPLAIN语句及用法
May 20 #MySQL
You might like
YB217、YB235、YB400浅听
2021/03/02 无线电
改造一台复古桌面收音机
2021/03/02 无线电
关于Iframe如何跨域访问Cookie和Session的解决方法
2013/04/15 PHP
深入eAccelerator与memcached的区别详解
2013/06/06 PHP
jQuery 打造动态渐变按钮 详细图文教程
2010/04/25 Javascript
JS命名空间的另一种实现
2013/08/09 Javascript
JavaScript实现按Ctrl键打开新页面
2014/09/04 Javascript
JavaScript学习笔记之定时器
2015/01/22 Javascript
JavaScript事件类型中UI事件详解
2016/01/14 Javascript
angularjs封装bootstrap时间插件datetimepicker
2016/06/20 Javascript
node.js报错:Cannot find module 'ejs'的解决办法
2016/12/14 Javascript
JS触摸与手势事件详解
2017/05/09 Javascript
ECharts地图绘制和钻取简易接口详解
2019/07/12 Javascript
Element Input输入框的使用方法
2020/07/26 Javascript
深入了解JavaScript词法作用域
2020/07/29 Javascript
浅谈Python处理PDF的方法
2017/11/10 Python
分析python切片原理和方法
2017/12/19 Python
Python实现统计给定列表中指定数字出现次数的方法
2018/04/11 Python
Python实战购物车项目的实现参考
2019/02/20 Python
Python pickle模块实现对象序列化
2019/11/22 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
2020/07/03 Python
python 统计list中各个元素出现的次数的几种方法
2021/02/20 Python
夏威夷咖啡公司:Hawaii Coffee Company
2019/09/19 全球购物
什么是Web Service?
2012/07/25 面试题
学生会竞选自荐信
2013/10/12 职场文书
大学在校生求职信范文
2013/11/21 职场文书
大学生职业生涯规划方案
2014/01/03 职场文书
幼儿园美术教学反思
2014/01/31 职场文书
会展策划与管理专业求职信
2014/06/09 职场文书
诉讼授权委托书范本
2014/10/05 职场文书
2015年幼儿园中班下学期工作总结
2015/05/22 职场文书
2019年大学推荐信
2019/06/24 职场文书
Angular性能优化之第三方组件和懒加载技术
2021/05/10 Javascript
python异常中else的实例用法
2021/06/15 Python
Android RecyclerView实现九宫格效果
2022/06/28 Java/Android
win11自动弹出虚拟键盘怎么关闭? Win11关闭虚拟键盘的技巧
2023/01/09 数码科技