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 相关文章推荐
数据库连接池
Apr 06 MySQL
MySQL COUNT函数的使用与优化
May 10 MySQL
linux下导入、导出mysql数据库命令的实现方法
May 26 MySQL
Mysql基础知识点汇总
May 26 MySQL
MySQL中varchar和char类型的区别
Nov 17 MySQL
关于k8s环境部署mysql主从的问题
Mar 13 MySQL
MySQL高级进阶sql语句总结大全
Mar 16 MySQL
navicat 连接Ubuntu虚拟机的mysql的操作方法
Apr 02 MySQL
详解MySQL的主键查询为什么这么快
Apr 03 MySQL
Mysql索引失效 数据库表中有索引还是查询很慢
May 15 MySQL
MySQL数据库实验之 触发器和存储过程
Jun 21 MySQL
MySQL深分页问题解决思路
Dec 24 MySQL
MYSQL如何查看操作日志详解
sql查询语句之平均分、最高最低分及排序语句
May 30 #MySQL
mysql5.5中文乱码问题解决的有用方法
深入理解MySQL中MVCC与BufferPool缓存机制
MYSQL事务的隔离级别与MVCC
详解Mysql数据库平滑扩容解决高并发和大数据量问题
MySQL中EXPLAIN语句及用法
May 20 #MySQL
You might like
php 获取页面中指定内容的实现类
2014/01/23 PHP
php实现读取手机客户端浏览器的类
2015/01/09 PHP
js获取html文件的思路及示例
2013/09/17 Javascript
优化javascript的执行效率一些方法总结
2013/12/25 Javascript
jsPDF导出pdf示例
2014/05/02 Javascript
谷歌浏览器调试JavaScript小技巧
2014/12/29 Javascript
JavaScript中join()方法的使用简介
2015/06/09 Javascript
基于JS实现的倒计时程序实例
2015/07/24 Javascript
JavaScript代码轻松实现网页内容禁止复制(代码简单)
2015/10/23 Javascript
node.js中grunt和gulp的区别详解
2017/07/17 Javascript
JSON对象转化为字符串详解
2017/08/11 Javascript
基于iScroll实现内容滚动效果
2018/03/21 Javascript
vue实现拖拽的简单案例 不超出可视区域
2019/07/25 Javascript
JS document form表单元素操作完整示例
2020/01/13 Javascript
vue仿携程轮播图效果(滑动轮播,下方高度自适应)
2021/02/11 Vue.js
Python代理抓取并验证使用多线程实现
2013/05/03 Python
老生常谈python的私有公有属性(必看篇)
2017/06/09 Python
python版学生管理系统
2018/01/10 Python
Python中一般处理中文的几种方法
2019/03/06 Python
python实现批量nii文件转换为png图像
2019/07/18 Python
Python学习笔记之文件的读写操作实例分析
2019/08/07 Python
Python 使用matplotlib模块模拟掷骰子
2019/08/08 Python
详解mac python+selenium+Chrome 简单案例
2019/11/08 Python
Pytorch evaluation每次运行结果不同的解决
2020/01/02 Python
Pytorch训练过程出现nan的解决方式
2020/01/02 Python
Pytorch中膨胀卷积的用法详解
2020/01/07 Python
Python的PIL库中getpixel方法的使用
2020/04/09 Python
使用jupyter notebook运行python和R的步骤
2020/08/13 Python
Python 多线程C段扫描、检测 Ping扫描脚本的实现
2020/09/03 Python
世界上最值得信赖的多日游在线市场:TourRadar
2018/07/20 全球购物
关于Java finally的面试题
2016/04/27 面试题
大学生就业自荐书
2014/06/16 职场文书
医学专业毕业生推荐信
2014/07/12 职场文书
领导个人查摆剖析材料
2014/10/29 职场文书
企业2014年度工作总结
2014/12/10 职场文书
MySQL详细讲解变量variables的用法
2022/06/21 MySQL