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 相关文章推荐
数据库的高级查询六:表连接查询:外连接(左外连接,右外连接,UNION关键字,连接中ON与WHERE的不同)
Apr 05 MySQL
mysql 8.0.24版本安装配置方法图文教程
May 12 MySQL
MySQL连接控制插件介绍
Sep 25 MySQL
MySQL七种JOIN类型小结
Oct 24 MySQL
mysql主从复制的实现步骤
Oct 24 MySQL
面试被问select......for update会锁表还是锁行
Nov 11 MySQL
Mysql忘记密码解决方法
Feb 12 MySQL
一文了解MySQL二级索引的查询过程
Feb 24 MySQL
MySQL日期时间函数知识汇总
Mar 17 MySQL
MySQL优化及索引解析
Mar 17 MySQL
MySQL 分区表中分区键为什么必须是主键的一部分
Mar 17 MySQL
mysql中关键词exists的用法实例详解
Jun 10 MySQL
MYSQL如何查看操作日志详解
sql查询语句之平均分、最高最低分及排序语句
May 30 #MySQL
mysql5.5中文乱码问题解决的有用方法
深入理解MySQL中MVCC与BufferPool缓存机制
MYSQL事务的隔离级别与MVCC
详解Mysql数据库平滑扩容解决高并发和大数据量问题
MySQL中EXPLAIN语句及用法
May 20 #MySQL
You might like
php mysql数据库操作类
2008/06/04 PHP
提高php运行速度的一些小技巧分享
2012/07/03 PHP
php中session退出登陆问题
2014/02/27 PHP
PHP简单获取视频预览图的方法
2015/03/12 PHP
简单谈谈php延迟静态绑定
2016/01/26 PHP
PHP版微信小店接口开发实例
2016/11/12 PHP
php实时倒计时功能实现方法详解
2017/02/27 PHP
解决php 处理 form 表单提交多个 name 属性值相同的 input 标签问题
2017/05/11 PHP
深入浅析安装PhpStorm并激活的步骤详解
2020/09/17 PHP
一个符号插入器 中用到的js代码
2007/09/04 Javascript
实现超用户体验 table排序javascript实现代码
2009/06/22 Javascript
JavaScript读取中文cookie时的乱码问题的解决方法
2009/10/14 Javascript
面向对象的编程思想在javascript中的运用上部
2009/11/20 Javascript
在JavaScript里嵌入大量字符串常量的实现方法
2013/07/07 Javascript
js全屏显示显示代码的三种方法
2013/11/11 Javascript
原生js实现复制对象、扩展对象 类似jquery中的extend()方法
2014/08/30 Javascript
jQuery Validate插件实现表单强大的验证功能
2015/12/18 Javascript
终于实现了!精彩的jquery弹幕效果
2016/07/18 Javascript
jQuery实现菜单栏导航效果
2017/08/15 jQuery
bootstrap 点击空白处popover弹出框隐藏实例
2018/01/24 Javascript
Node.js中DNS模块学习总结
2018/02/28 Javascript
Node 升级到最新稳定版的方法分享
2018/05/17 Javascript
vue.js单文件组件中非父子组件的传值实例
2018/09/13 Javascript
微信小程序中显示倒计时代码实例
2019/05/09 Javascript
vue中父子组件的参数传递和应用示例
2021/01/04 Vue.js
python实现的二叉树定义与遍历算法实例
2017/06/30 Python
Python微信公众号开发平台
2018/01/25 Python
Django中如何使用sass的方法步骤
2019/07/09 Python
python获取Linux发行版名称
2019/08/30 Python
python 多维高斯分布数据生成方式
2019/12/09 Python
美国性感内衣店:Yandy
2018/06/12 全球购物
墨西哥购物网站:Elektra
2020/01/21 全球购物
物流专业大学生的自我鉴定
2013/11/13 职场文书
加强作风建设心得体会
2014/10/22 职场文书
Mysql数据库表中为什么有索引却没有提高查询速度
2022/02/24 MySQL
MySQL的InnoDB存储引擎的数据页结构详解
2022/03/03 MySQL