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 相关文章推荐
仅用一句SQL更新整张表的涨跌幅、涨跌率的解决方案
May 06 MySQL
如何用Navicat操作MySQL
May 12 MySQL
MySQL查看表和清空表的常用命令总结
May 26 MySQL
MySQL GRANT用户授权的实现
Jun 18 MySQL
MySQL七种JOIN类型小结
Oct 24 MySQL
详解MySQL中timestamp和datetime时区问题导致做DTS遇到的坑
Dec 06 MySQL
Mysql外键约束的创建与删除的使用
Mar 03 MySQL
简单聊一聊SQL注入及防止SQL注入
Mar 23 MySQL
MySql数据库 查询时间序列间隔
May 11 MySQL
MySQL sql模式设置引起的问题
May 15 MySQL
MySQL数据库如何查看表占用空间大小
Jun 10 MySQL
MySql统计函数COUNT的具体使用详解
Aug 14 MySQL
MYSQL如何查看操作日志详解
sql查询语句之平均分、最高最低分及排序语句
May 30 #MySQL
mysql5.5中文乱码问题解决的有用方法
深入理解MySQL中MVCC与BufferPool缓存机制
MYSQL事务的隔离级别与MVCC
详解Mysql数据库平滑扩容解决高并发和大数据量问题
MySQL中EXPLAIN语句及用法
May 20 #MySQL
You might like
php 正则表达式小结
2009/08/31 PHP
PHP字符串的递增和递减示例介绍
2014/02/11 PHP
Drupal7 form表单二次开发要点与实例
2014/03/02 PHP
深入了解PHP中的Array数组和foreach
2016/11/06 PHP
php自定义截取中文字符串-utf8版
2017/02/27 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
2017/09/16 PHP
php ActiveMQ的安装与使用方法图文教程
2020/02/23 PHP
JavaScript 图片预览效果 推荐
2009/12/22 Javascript
JSON+HTML实现国家省市联动选择效果
2014/05/18 Javascript
JavaScript实现的使用键盘控制人物走动实例
2014/08/27 Javascript
Nodejs学习笔记之Stream模块
2015/01/13 NodeJs
jQuery过滤选择器详解
2015/01/13 Javascript
window.open()实现post传递参数
2015/03/12 Javascript
JavaScript获取页面中表单(form)数量的方法
2015/04/03 Javascript
Bootstrap每天必学之表格
2015/11/23 Javascript
jQuery遮罩层实例讲解
2017/05/11 jQuery
基于mpvue的简单弹窗组件mptoast使用详解
2019/08/02 Javascript
Vertx基于EventBus发送接受自定义对象
2020/11/16 Javascript
理解生产者消费者模型及在Python编程中的运用实例
2016/06/26 Python
Python 调用PIL库失败的解决方法
2019/01/08 Python
Pandas读写CSV文件的方法示例
2019/03/27 Python
Python Django切换MySQL数据库实例详解
2019/07/16 Python
Python八皇后问题解答过程详解
2019/07/29 Python
pytorch制作自己的LMDB数据操作示例
2019/12/18 Python
Python加密模块的hashlib,hmac模块使用解析
2020/01/02 Python
Python 将 QQ 好友头像生成祝福语的实现代码
2020/05/03 Python
如何用python批量调整视频声音
2020/12/22 Python
请解释virtual关键字的含义
2015/06/17 面试题
元旦晚会策划方案
2014/02/18 职场文书
计算机维护专业推荐信
2014/02/27 职场文书
毕业生代领毕业材料的授权委托书
2014/09/29 职场文书
2014年远程教育工作总结
2014/12/09 职场文书
2016年端午节寄语
2015/12/04 职场文书
爱心捐款倡议书:点燃希望,传递温暖
2019/11/04 职场文书
PHP命令行与定时任务
2021/04/01 PHP
浅谈Redis在直播场景的实践方案
2021/04/27 Redis