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对于模糊查询like的一些汇总
May 09 MySQL
MySQL 使用自定义变量进行查询优化
May 14 MySQL
虚拟机linux端mysql数据库无法远程访问的解决办法
May 26 MySQL
MySQL实例精讲单行函数以及字符数学日期流程控制
Oct 15 MySQL
MySQL利用UNION连接2个查询排序失效详解
Nov 20 MySQL
mysql sum(if())和count(if())的用法说明
Jan 18 MySQL
MySQL数据库完全卸载的方法
Mar 03 MySQL
MySQL 分区表中分区键为什么必须是主键的一部分
Mar 17 MySQL
Linux系统下MySQL配置主从分离的步骤
Mar 21 MySQL
MySQL 外连接语法之 OUTER JOIN
Apr 09 MySQL
mysql数据库隔离级别详解
Jun 16 MySQL
Mysql数据库group by原理详解
Jul 07 MySQL
MYSQL如何查看操作日志详解
sql查询语句之平均分、最高最低分及排序语句
May 30 #MySQL
mysql5.5中文乱码问题解决的有用方法
深入理解MySQL中MVCC与BufferPool缓存机制
MYSQL事务的隔离级别与MVCC
详解Mysql数据库平滑扩容解决高并发和大数据量问题
MySQL中EXPLAIN语句及用法
May 20 #MySQL
You might like
PHP 已经成熟
2006/12/04 PHP
php 显示指定路径下的图片
2009/10/29 PHP
使用dump函数,给php加断点测试
2013/06/25 PHP
关于PHP语言构造器介绍
2013/07/08 PHP
PHP入门之常量简介和系统常量
2014/05/12 PHP
php微信开发之关键词回复功能
2018/06/13 PHP
Laravel 自定命令以及生成文件的例子
2019/10/23 PHP
jQuery each()小议
2010/03/18 Javascript
js实现兼容IE6与IE7的DIV高度
2010/05/13 Javascript
让IE6支持min-width和max-width的方法
2010/06/25 Javascript
基于jquery的一行代码轻松实现拖动效果
2010/12/28 Javascript
js相册效果代码(点击创建即可)
2013/04/16 Javascript
javascript跟随滚动效果插件代码(javascript Follow Plugin)
2013/08/03 Javascript
IE8中动态创建script标签onload无效的解决方法
2014/12/22 Javascript
JQuery判断checkbox是否选中及其它复选框操作方法合集
2015/06/01 Javascript
etmvc+jQuery EasyUI+combobox多值操作实现角色授权实例
2016/11/09 Javascript
JavaScript常用正则函数用法示例
2017/01/23 Javascript
JavaScript使用原型和原型链实现对象继承的方法详解
2017/04/05 Javascript
vue+vant-UI框架实现购物车的复选框全选和反选功能
2019/11/05 Javascript
jQuery实现图片切换效果
2020/10/19 jQuery
详解Python中DOM方法的动态性
2015/04/11 Python
python使用Queue在多个子进程间交换数据的方法
2015/04/18 Python
python列出目录下指定文件与子目录的方法
2015/07/03 Python
python 爬虫出现403禁止访问错误详解
2017/03/11 Python
django允许外部访问的实例讲解
2018/05/14 Python
python中报错&quot;json.decoder.JSONDecodeError: Expecting value:&quot;的解决
2019/04/29 Python
python分布式计算dispy的使用详解
2019/12/22 Python
如何基于python测量代码运行时间
2019/12/25 Python
python itsdangerous模块的具体使用方法
2020/02/17 Python
20行Python代码实现视频字符化功能
2020/04/13 Python
Python基于pip实现离线打包过程详解
2020/05/15 Python
HTML5+WebSocket实现多文件同时上传的实例
2016/12/29 HTML / CSS
htnl5利用svg页面高斯模糊的方法
2018/07/20 HTML / CSS
印尼最大的婴儿用品购物网站:Orami
2017/09/28 全球购物
法律系毕业生求职信
2014/05/28 职场文书
MySQL连表查询分组去重的实现示例
2021/07/01 MySQL